Azure Web App启用AAD(SERVICE PRINCIPAL)认证
Web Python Flask 代码:
app.py:
import identity
app_config.py:
import os
import identity.web
from flask import Flask, redirect, render_template, request, session, url_for,jsonify
from flask_session import Session
import app_config
app = Flask(__name__)
app.config.from_object(app_config)
Session(app)
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
auth = identity.web.Auth(
session=session,
authority=app.config.get("AUTHORITY"),
client_id=app.config["CLIENT_ID"],
client_credential=app.config["CLIENT_SECRET"],
)
@app.route("/login")
def login():
return render_template("login.html", version=identity.__version__, **auth.log_in(
scopes=app_config.SCOPE1, # Have user consent to scopes during log-in
redirect_uri=url_for("auth_response", _external=True),
))
@app.route(app_config.REDIRECT_PATH)
def auth_response():
result = auth.complete_log_in(request.args)
if "error" in result:
return render_template("auth_error.html", result=result)
return redirect(url_for("index"))
@app.route("/logout")
def logout():
return redirect(auth.log_out(url_for("index", _external=True)))
@app.before_request
def before():
url = request.path
print(url)
pass_list = ['/logout', '/getAToken','/login']
suffix = url.endswith('.png') or url.endswith('.css') or url.endswith('.js')
if url in pass_list or suffix:
pass
elif not auth.get_user():
return redirect(url_for("login"))
else:
pass
@app.route("/")
def index():
user = auth.get_user()
return render_template('index.html', user=user, version=identity.__version__)
@app.route("/token")
def token():
token = auth.get_token_for_user(app_config.SCOPE2)
if "error" in token:
return redirect(url_for("login"))
return jsonify(token)
@app.route("/user")
def user():
user = auth.get_user()
return jsonify(user)
# API End
# Main
if __name__ == "__main__":
app.run()
# Application (client) ID of app registration
CLIENT_ID = 'fe861e91-b217f-4585-8dfa-ddaa7849b0b4'
# Application's generated client secret: never check this into source control!
CLIENT_SECRET = 'FyF8Q~O7f2m56QpRqjg_1op12QwH0j6DbjqEq.cCu'
# AUTHORITY = "https://login.microsoftonline.com/common" # For multi-tenant app
AUTHORITY = f"https://login.microsoftonline.com/878d19338-a5c4-4f48-bd1c-2dbf8a70f3c5"
REDIRECT_PATH = "/getAToken" # Used for forming an absolute URL to your redirect URI.
# The absolute URL must match the redirect URI you set
# in the app's registration in the Azure portal.
# You can find more Microsoft Graph API endpoints from Graph Explorer
# https://developer.microsoft.com/en-us/graph/graph-explorer
ENDPOINT = 'https://graph.microsoft.com/v1.0/users' # This resource requires no admin consent
# You can find the proper permission names from this document
# https://docs.microsoft.com/en-us/graph/permissions-reference
#SCOPE = ["openid profile"]
SCOPE1 = ["User.ReadBasic.All"]
SCOPE2 = ["User.ReadBasic.All openid profile email"]
# Tells the Flask-session extension to store sessions in the filesystem
SESSION_TYPE = "filesystem"
# Using the file system will not work in most production systems,
# it's better to use a database-backed session store instead.
validateIDToken.py
from azure_ad_verify_token import verify_jwt
azure_ad_app_id = 'fe861ed91-b27f-4585-8dfa-ddaa7849b0b4'
azure_ad_issuer = 'https://login.microsoftonline.com/878d1938-a5c4-4f48-bdd1c-2dbf8a70f3c5/v2.0'
azure_ad_jwks_uri = 'https://login.microsoftonline.com/878d1938-a5dc4-4f48-bd1c-2dbf8a70f3c5/discovery/v2.0/keys'
payload = verify_jwt(
token= 'xxx',
valid_audiences=azure_ad_app_id,
issuer=azure_ad_issuer,
jwks_uri=azure_ad_jwks_uri,
verify=True,
)
print(payload)
#Signature verification failed
#Invalid authorization token
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Microsoft Identity Python Web App</title>
</head>
<body>
<h1>Microsoft Identity Python Web App</h1>
{% if user_code %}
<ol>
<li>To sign in, type <b>{{ user_code }}</b> into
<a href='{{ auth_uri }}' target=_blank>{{ auth_uri }}</a>
to authenticate.
</li>
<li>And then <a href="{{ url_for('auth_response') }}">proceed</a>.</li>
</ol>
{% else %}
<ul><li><a href='{{ auth_uri }}'>Sign In</a></li></ul>
{% endif %}
<hr>
<footer style="text-align: right">Powered by Identity Web {{ version }}</footer>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Microsoft Identity Python Web App</title>
</head>
<body>
<h1>Microsoft Identity Python Web App</h1>
<h2>Welcome {{ user.get("email") }}</h2>
<hr>
<a href="/logout">Logout</a><br/>
<footer style="text-align: left">Powered by Identity Web {{ version }}</footer>
</body>
</html>