簡體   English   中英

Azure AD 身份驗證 Python Web API

[英]Azure AD Authentication Python Web API

我正在嘗試使用 OAuth2 對用戶進行身份驗證並訪問資源。 但是,我在這樣做時遇到了一些問題。 這是詳細信息。

  1. 我已在 Azure 門戶上將該應用程序注冊為 Web Api
  2. 我想編寫一個 python 腳本,通過它我可以請求授權碼,然后是訪問令牌

挑戰:

  1. 我沒有重定向網址。 我不確定我可以在這里使用什么
  2. 當我使用該鏈接在瀏覽器中獲取授權碼時,它會要求我登錄 Azure。 我如何確保它也要求我通過 Python API 登錄?

這是我用來獲取身份驗證代碼的 python 腳本:

import requests
import json

'''Request Authorization code template

https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&resource=https%3A%2F%2Fservice.contoso.com%2F
&state=12345

'''

payload = {'client_id': '***', 'response_type': 'code', 'response_mode': 'query',
           'resource': '***'}
get_authorization_code = requests.get('https://login.microsoftonline.com/tenant/oauth2/authorize',
                        params=payload, verify=False)
print get_authorization_code

我得到的此代碼的響應是:響應 [200]

授權代碼授予流程 ( response_type=code ) 期望您在用戶代理(即瀏覽器或瀏覽器控件)中實際將用戶發送到該 URL。 用戶將看到登錄過程(例如用戶名、密碼、多重身份驗證等),當所有這些完成后,瀏覽器將被重定向到redirect_uri

如果您將 Web 應用程序編碼為客戶端(您只需將用戶(在他們的瀏覽器中)發送到您構建的 URL,然后在redirect_uri上托管一個頁面以接收授權代碼,那么這一切都非常簡單)登錄完成)。 但是,您似乎正在編寫控制台應用程序(或其他應用程序,在該應用程序中將用戶發送到您可以捕獲最終重定向的瀏覽器控件是不切實際的)。 您有幾個選項,具體取決於腳本是否在高度安全的環境中運行。

將 API 作為應用程序調用

這可能是最容易實現的,但需要客戶端在高度信任的安全環境中運行。 應用程序將以自身身份(而不是以用戶身份)進行身份驗證,獲取訪問令牌,並發出 API 請求。 這是OAuth 2.0 客戶端憑據授予流程。

您將需要:

  • 在 Azure AD 中將您的客戶端應用程序注冊為 Web 應用程序/Web API(這很重要,因為它告訴 Azure AD 這是一個機密客戶端,並允許您關聯應用程序的憑據(密碼或證書)。
  • 聲明您的客戶端應用程序需要訪問您的 API(將注冊為不同的 Web 應用程序/Web API)。

使用 Python,最簡單的方法是使用ADAL for Python 例如,要在使用證書進行身份驗證時獲取訪問令牌:

import adal
context = adal.AuthenticationContext('https://login.microsoftonline.com/{tenant-id}')
token = context.acquire_token_with_client_certificate(
    "https://api.example.com",
    "{client-id}",  
    '{certificate-content}', 
    '{certificate-thumbprint}')

請參閱GitHub 上的其他詳細信息

以用戶身份調用 API,使用設備代碼流

設備流程允許有限輸入體驗(例如電視或很少使用的控制台應用程序)在用戶上下文中獲取 OAuth 2.0 訪問令牌,同時允許用戶在不同的具有更好輸入功能的設備(例如在智能手機或台式計算機上)。

您將需要:

  • 在 Azure AD 中將您的客戶端應用程序注冊為本機客戶端應用程序(這很重要,因為它告訴 Azure AD 這是一個公共客戶端,這允許應用程序獲取具有委派權限的訪問令牌,而無需應用程序進行身份驗證(因為公共客戶端可以'不要對用戶保密)。
  • 聲明您的客戶端應用程序需要訪問您的 API(將注冊為單獨的 Web 應用程序/Web API)。

設備代碼流包括:

  1. 客戶端應用程序向 Azure AD 發出請求以獲取設備代碼。 此設備代碼會顯示給用戶(連同 URL)。
  2. 在單獨的設備上(或例如在同一設備中的成熟瀏覽器中),用戶訪問給定的 URL,並輸入給定的設備代碼。 系統會提示用戶登錄,並在登錄時顯示成功消息。
  3. 同時,客戶端應用程序會定期輪詢 Azure AD 以查看用戶是否已兌換設備代碼(並已登錄)。 如果是,則客戶端應用程序收到訪問令牌。

對於 Python,將 ADAL 用於 Python 再次很有用。 獲取設備代碼的請求如下所示:

context = adal.AuthenticationContext('https://login.microsoftonline.com/{tenant-id}')
code = context.acquire_user_code('https://api.example.com', '{client-id}')
print(code['message'])

定期輪詢請求如下所示:

token = context.acquire_token_with_device_code('https://api.example.com', code, '{client-id}')

請參閱GitHub 上的其他詳細信息

我剛剛接受了這個挑戰,從一些使用 oauth2 和 azure 的 webapi 獲取數據。

不喜歡使用 adal 庫的想法,因為我們的案例不再支持 adal 並且看起來像使用 oauth2 我可以在不需要新庫的情況下獲得令牌。

我做到了:

https://github.com/pablodav/curlnagios/commit/ca7462be13acb2637553ab95eadcfc0f0b7aecab#diff-332569aae421078a8053c3b1140440d5R53

import requests
import json

def get_token(auth_url, client_id, scope, client_secret, grant_type = 'client_credentials'):
    """
     return: tuple dict with access_token, status_code
        {'access_token': 'tokenid'
        'expires_in': 3600,
        'ext_expires_in': 0,
        'token_type': 'Bearer'}, 200
    """
    # Request access token:
    # https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-access-token

    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    url =auth_url
    data = { "client_id": client_id,
            "scope": scope,
            "client_secret": client_secret,
            "grant_type": grant_type
        }
    # requests doc http://docs.python-requests.org/en/v0.10.7/user/quickstart/#custom-headers
    r = requests.post(url=url, data=data, headers=headers)

    return r.json(), r.status_code

# Change these vars to test:
auth_url = 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
client_id = '6731de76-14a6-49ae-97bc-6eba6914391e'
scope = 'https://company.onmicrosoft.com/some-unique-number-for-scope/.default'
client_secret = "client password secret here"


url = 'http://bioforestws-sandbox.group.upm.com/api/interface/sap/stockmovement'
get_token = get_token(auth_url, client_id, scope, client_secret)
access_token = get_token[0]['access_token']
header_token = {"Authorization": "Bearer {}".format(access_token)}
rt = requests.get(url=url_check, headers=header_token)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM