Azure Python Flask App-AD身份验证问题 [英] Azure Python flask App - AD authentication issue

查看:122
本文介绍了Azure Python Flask App-AD身份验证问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能有点复杂,所以我会尽力而为.

当前解决方案

我有一个python flask应用程序,它将部署到Azure内的应用程序服务中.我希望用户通过Azure AD身份验证登录到应用程序服务.为此,我使用了ADAL库,因为我发现了一些可以做到这一点的代码.

我已针对Azure AD注册了该应用程序,以获取应用程序ID和应用程序密钥.为此,我使用了本教程:

This could be a little complicated to explain, so will do my best.

Current Solution

I have a python flask app, which will be deployed to an App Service within Azure. I want the user to login to the app service Via Azure AD authentication. To do this i am using the ADAL library, as i found some code which works to do this.

I have registered the application against Azure AD in order to get the App ID and the App Secret. To do this, i used this tutorial: https://docs.microsoft.com/en-gb/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-redirect-uris-to-your-application

app.py

import os
import urllib.parse
import uuid

import adal
import flask
import requests

import config
import logging

os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # enable non-HTTPS for testing

APP = flask.Flask(__name__, template_folder='static/templates')
APP.debug = True
APP.secret_key = 'development'
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

SESSION = requests.Session()

@APP.route('/')
def homepage():
    """Render the home page."""
    logging.info('test')
    logger.debug("test1")
    return flask.render_template('homepage.html', sample='ADAL')

@APP.route('/login')
def login():
    """Prompt user to authenticate."""
    auth_state = str(uuid.uuid4())
    SESSION.auth_state = auth_state

    # For this sample, the user selects an account to authenticate. Change
    # this value to 'none' for "silent SSO" behavior, and if the user is
    # already authenticated they won't need to re-authenticate.
    prompt_behavior = 'select_account'

    params = urllib.parse.urlencode({'response_type': 'code',
                                     'client_id': config.CLIENT_ID,
                                     'redirect_uri': config.REDIRECT_URI,
                                     'state': auth_state,
                                     'resource': config.RESOURCE,
                                     'prompt': prompt_behavior})

    return flask.redirect(config.AUTHORITY_URL + '/oauth2/authorize?' + params)

@APP.route('/login/authorized')
def authorized():
    """Handler for the application's Redirect Uri."""
    code = flask.request.args['code']
    auth_state = flask.request.args['state']
    if auth_state != SESSION.auth_state:
        raise Exception('state returned to redirect URL does not match!')
    auth_context = adal.AuthenticationContext(config.AUTHORITY_URL, api_version=None)
    token_response = auth_context.acquire_token_with_authorization_code(
        code, config.REDIRECT_URI, config.RESOURCE, config.CLIENT_ID, config.CLIENT_SECRET)
    SESSION.headers.update({'Authorization': f"Bearer {token_response['accessToken']}",
                            'User-Agent': 'adal-sample',
                            'Accept': 'application/json',
                            'Content-Type': 'application/json',
                            'SdkVersion': 'sample-python-adal',
                            'return-client-request-id': 'true'})
    return flask.redirect('/graphcall')

@APP.route('/graphcall')
def graphcall():
    """Confirm user authentication by calling Graph and displaying some data."""
    endpoint = config.RESOURCE + config.API_VERSION + '/me'
    http_headers = {'client-request-id': str(uuid.uuid4())}
    graphdata = SESSION.get(endpoint, headers=http_headers, stream=False).json()
    return flask.render_template('graphcall.html',
                                 graphdata=graphdata,
                                 endpoint=endpoint,
                                 sample='ADAL')

if __name__ == '__main__':
    APP.run(debug=True)
    APP.run()

config.py

CLIENT_ID = 'd****************************'
CLIENT_SECRET = 'D******************************'
REDIRECT_URI = 'http://localhost:5000/login/authorized'

# AUTHORITY_URL ending determines type of account that can be authenticated:
# /organizations = organizational accounts only
# /consumers = MSAs only (Microsoft Accounts - Live.com, Hotmail.com, etc.)
# /common = allow both types of accounts
AUTHORITY_URL = 'https://login.microsoftonline.com/common'

AUTH_ENDPOINT = '/oauth2/v2.0/authorize'
TOKEN_ENDPOINT = '/oauth2/v2.0/token'

RESOURCE = 'https://graph.microsoft.com/'
API_VERSION = 'v1.0'
SCOPES = ['User.Read'] # Add other scopes/permissions as needed.


# This code can be removed after configuring CLIENT_ID and CLIENT_SECRET above.
if 'ENTER_YOUR' in CLIENT_ID or 'ENTER_YOUR' in CLIENT_SECRET:
    print('ERROR: config.py does not contain valid CLIENT_ID and CLIENT_SECRET')
    import sys
    sys.exit(1)

Currently when logging into the app, i am presented with the login screen, which i can login with, i think am passed to my organisations password screen for the login. After that the application fails to get the bearer token. which then redirects the application back to the home page.

Questions

  • Is there a way where i dont have to use the Azure AD Authorization for the app service and i can just authorize with Azure AD without it.
  • What is the better way to do this.

Or can i authenticate with Azure AD without having to use the ADAL library and use the builtin Azure AD authorization for when logging into my flask app service.

I understand this may not be explained very well, so any questions or more info, please let me know

Thanks in advance.

解决方案

If I understand your question correctly, you would rather use builtin Azure AD authentication than ADAL library.

It is very convenient to use builtin Azure AD authentication if you just want to use the sign in feature, you needn't to modify your code. But if you want to get the access token, you need to collect it yourself.

How to get the access token?

From your server code, the provider-specific tokens are injected into the request header, so you can easily access them.

App Service provides a built-in token store, which is a repository of tokens that are associated with the users of your web apps, but you must write code to collect, store, and refresh these tokens in your application.

Update:

这篇关于Azure Python Flask App-AD身份验证问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆