Azure AD 身份验证 Python Web API
问题描述
我正在尝试使用 OAuth2 对用户进行身份验证并访问资源.但是,我在这样做时遇到了一些问题.以下是详细信息.
- 我已在 Azure 门户上将应用注册为 Web Api
- 我想编写一个 python 脚本,通过它我可以请求授权码,然后是访问令牌
挑战:
- 我没有重定向网址.我不确定我可以在这里使用什么
- 当我使用链接在浏览器中获取授权码时,它要求我登录 Azure.如何确保它也要求我通过 Python API 登录?
这是我用来获取身份验证代码的 python 脚本:
导入请求导入json'''请求授权码模板https://login.microsoftonline.com/{tenant}/oauth2/authorize?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&response_type=代码&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=查询&resource=https%3A%2F%2Fservice.contoso.com%2F&状态=12345'''有效载荷 = {'client_id': '***', 'response_type': 'code', 'response_mode': 'query',资源":***"}get_authorization_code = requests.get('https://login.microsoftonline.com/tenant/oauth2/authorize',参数=有效负载,验证=假)打印 get_authorization_code
我得到的此代码的响应是:响应 [200]
解决方案授权代码授予流程 (response_type=code
) 期望您在用户代理(即浏览器或浏览器控件)到该 URL.用户将看到登录过程(例如用户名、密码、多重身份验证等),当所有这些都完成后,浏览器将被重定向到 redirect_uri
.p>
如果您将 Web 应用程序编码为客户端,这一切都非常简单(您只需将用户(在他们的浏览器中)发送到您构建的 URL,并在 redirect_uri
以在登录完成后接收授权码).但是,您似乎正在编写控制台应用程序(或其他将用户发送到可以捕获最终重定向的浏览器控件不切实际的应用程序)的脚本.您有几个选项,具体取决于脚本是否在高度安全的环境中运行.
将 API 作为应用程序调用
这可能是最简单的实现方式,但需要客户端在高度信任的安全环境中运行.应用程序将以自身身份(而不是以用户身份)进行身份验证,获取访问令牌,并发出 API 请求.这是 OAuth 2.0 客户端凭据授予流程.
您需要:
- 在 Azure AD 中将您的客户端应用程序注册为 Web 应用程序/Web API(这很重要,因为它告诉 Azure AD 这是一个机密客户端,并允许您关联凭据(密码或证书).
- 声明您的客户端应用需要访问您的 API(将注册为不同的网络应用/网络 API).
对于 Python,最简单的方法是使用 ADAL for Python.例如,在使用证书进行身份验证时获取访问令牌:
导入adalcontext = adal.AuthenticationContext('https://login.microsoftonline.com/{tenant-id}')token = context.acquire_token_with_client_certificate(https://api.example.com",{client-id}",'{证书内容}','{证书指纹}')
请参阅 GitHub 上的其他详细信息.
以用户身份调用 API,使用设备代码流
设备流程允许有限输入体验(例如电视或很少使用的控制台应用程序)在用户的上下文中获取 OAuth 2.0 访问令牌,同时允许用户在具有更好输入功能的不同设备上执行实际登录(例如在智能手机或台式计算机上).
您需要:
- 在 Azure AD 中将您的客户端应用程序注册为本机客户端应用程序(这很重要,因为它告诉 Azure AD 这是一个公共客户端,它允许应用程序通过委托获取访问令牌未经应用身份验证的权限(因为公共客户端无法对用户保密).
- 声明您的客户端应用需要访问您的 API(将注册为单独的网络应用/网络 API).
设备代码流程包括:
- 客户端应用向 Azure AD 发出请求以获取设备代码.此设备代码会显示给用户(连同 URL).
- 在单独的设备上(或者,例如,在同一设备上的成熟浏览器中),用户访问给定的 URL,并输入给定的设备代码.系统会提示用户登录,并在用户登录时显示成功消息.
- 同时,客户端应用会定期轮询 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}')打印(代码['消息'])
定期轮询请求如下所示:
token = context.acquire_token_with_device_code('https://api.example.com', code, '{client-id}')
请参阅 GitHub 上的其他详细信息.
I'm trying to get the user authenticated using OAuth2 and access resources. However, I'm having some issues doing so. Here are the details.
- I've registered the app as a Web Api on the Azure portal
- I want to write a python script through which I can request an authorization code and then the access token
Challenges:
- I don't have redirect url. I'm not sure what I can use here
- When I use the link to get the authorization code in the browser, it asks me to sign in to Azure. How can I make sure that it asks me to login through the Python API as well?
Here's the python script that I'm using just to get the authentication code:
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
Response for this code I get is : Response [200]
解决方案The Authorization Code Grant flow (response_type=code
) expects you to actually send the user, in a user-agent (i.e. a browser or a browser control) to that URL. The user will be presented with the sign-in process (e.g. username, password, multi-factor authentication, etc.) and when all that is done, the browser will be redirected to the redirect_uri
.
This is all very simple if you're coding a web app as the client (you just send the user (in their browser) to the URL you've constructed, and you host a page at the redirect_uri
to receive the authorization code after the sign-in completes). It seems, however, that you are maybe scripting a console app (or other app where it's impractical to send the user to a browser control where you can catch the eventual redirect). You have a few options, depending on whether or not the script is running in a highly-secure environment.
To call the API as an application
This is probably the simplest to implement, but requires the client to be running in a high-trust secure environment. The application will authenticate as itself (not as a user), obtain an access token, and make the API request. This is the OAuth 2.0 Client Credentials Grant flow.
You will need to:
- Register your client app in Azure AD as a web app/web API (this is important, as it tells Azure AD that this is a confidential client, and allows you to associate credentials (a password or a certificate) for the app.
- Declare that your client app requires access to your API (which would be registered as a different web app/web API).
With Python, the easiest way to do this is to use ADAL for Python. For example, to obtain an access token while authenticating with a certificate:
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}')
See additional details on GitHub.
To call the API as a user, using the device code flow
The device flow allows limited-input experiences (e.g. think a TV, or a seldom-used console app) to obtain an OAuth 2.0 access token in the context of a user, while allowing the user to perform the actual sign-in on a different device with better input capabilities (e.g. on a smartphone or desktop computer).
You will need to:
- Register your client app in Azure AD as a native client app (this is important, as it tells Azure AD that this is a public client, which allows the app to get an access token with delegated permissions without the app authenticating (because public clients can't keep a secret from the user).
- Declare that your client app requires access to your API (which would be registered as a separate web app/web API).
The device code flow consists of:
- The client app makes a request to Azure AD to get an device code. This device code is displayed to the user (along with a URL).
- On a separate device (or, e.g. in full-fledged browser in the same device), the user visits the given URL, and inputs the given device code. The user is prompted to sign in and is shows a success message when they do so.
- Meanwhile, the client app periodically polls Azure AD to see if the user has redeemed the device code (and signed in). If yes, the client app received the access token.
With Python, it is again useful to use ADAL for Python. The request to get the device code would look like this:
context = adal.AuthenticationContext('https://login.microsoftonline.com/{tenant-id}')
code = context.acquire_user_code('https://api.example.com', '{client-id}')
print(code['message'])
The periodic polling requests look like this:
token = context.acquire_token_with_device_code('https://api.example.com', code, '{client-id}')
See additional details on GitHub.
相关文章