Flask-Admin authentication through oAuth
Flask-Admin provides the examples of authentication with Flask-Login and Flask-Security. Here is an example how to authenticate using Microsoft oAuth.
Create an application in Microsoft Application Registration Portal.
Add admin_auth.py
.
import jwt
from flask import Blueprint, url_for, request, session, redirect
from flask_oauthlib.client import OAuth
APP_KEY = '...'
APP_SECRET = '...'
ALLOWED_IDS = ['user@domain.com']
admin_auth_blueprint = Blueprint('admin_auth', __name__)
oauth = OAuth()
azure = oauth.remote_app(
'azure',
consumer_key=APP_KEY,
consumer_secret=APP_SECRET,
request_token_params={'scope': 'openid profile email'},
base_url='https://graph.microsoft.com/v1.0/',
request_token_url=None,
access_token_method='POST',
access_token_url='https://login.microsoftonline.com/common/oauth2/v2.0/token',
authorize_url='https://login.microsoftonline.com/common/oauth2/v2.0/authorize')
def is_authenticated():
return session.get('admin_authenticated', False)
@admin_auth_blueprint.route('/')
def login():
if request.args.get('code'):
response = azure.authorized_response()
id_token = jwt.decode(response['id_token'], verify=False)
id = id_token.get('email') or id_token.get('preferred_username')
if id in ALLOWED_IDS:
session['admin_authenticated'] = id
return redirect(url_for('admin.index'))
return 'No access', 403
else:
callback_url = url_for('admin_auth.login', _external=True)
return azure.authorize(callback=callback_url)
@admin_auth_blueprint.route('/logout')
def logout():
del session['admin_authenticated']
return redirect('/')
For admin part create an AuthMixin
with is_accessible
and inaccesibble_callback
methods
and use it in admin views.
from flask_admin import Admin
from flask_admin.contrib.mongoengine import ModelView
class AuthMixin(object):
def is_accessible(self):
return is_authenticated()
def inaccessible_callback(self, name, **kwargs):
return redirect(url_for('admin_auth.login'))
class MyModelView(AuthMixin, ModelView):
pass
adm = Admin(...)
adm.add_view(MyModelView(MyModel))
adm.add_link(MenuLink(name='Logout', endpoint='admin_auth.logout'))
Register the admin_auth_blueprint
blueprint in the Flask app.