Azure 跨不同的Microsoft租户搜索用户信息

Azure 跨不同的Microsoft租户搜索用户信息,azure,azure-functions,microsoft-graph-api,Azure,Azure Functions,Microsoft Graph Api,我希望能够跨多个租户搜索用户,因此我的想法是创建一个在HTTP触发的Azure函数上运行的python脚本。此python脚本可以通过服务主体对不同租户的Microsoft Graph API进行身份验证,然后搜索用户并返回数据。这是一个好主意还是有更好的方法呢?让我们讨论一下这项成就 我发现一个多租户azure ad应用程序就足以通过graph api查询不同租户中的用户。例如,有2个租户,我在azure ad app registration中创建了一个多租户应用程序,之后我生成了客户端密码

我希望能够跨多个租户搜索用户,因此我的想法是创建一个在HTTP触发的Azure函数上运行的python脚本。此python脚本可以通过服务主体对不同租户的Microsoft Graph API进行身份验证,然后搜索用户并返回数据。这是一个好主意还是有更好的方法呢?

让我们讨论一下这项成就

我发现一个
多租户
azure ad应用程序就足以通过graph api查询不同租户中的用户。例如,有2个租户,我在azure ad app registration中创建了一个多租户应用程序,之后我生成了客户端密码并添加了
User.Read.All
的api权限

现在我有一个应用程序,它的客户端id和“租户a”中的秘密。接下来,访问
https://login.microsoftonline.com/{tenant_b}/adminconsent?client_id={client id}
在浏览器中,在使用tenant_b中的管理员帐户登录后,将出现一个“权限”窗口,使应用程序在tenant_b中具有权限,在获得同意后,您将看到在租户a中创建的应用程序出现在租户b中的
企业应用程序列表中

现在我们需要为不同的租户生成访问令牌。有必要为每个租户生成访问令牌,因为我试图使用
common
替换请求中的域(
https://login.microsoftonline.com/common/oauth2/v2.0/token
),可以成功生成访问令牌,但该令牌不能在api中用于查询用户信息。查询用户api需要用户主体名称作为输入参数。例如,我有一个用户的帐户是'bob@tenant_b.onmicrosoft.com,使用account作为参数可以获得响应,但是如果我使用'bob'作为参数,它将返回'Resource xxx不存在…'

我不是python方面的专家,我只找到了一个示例,并用它成功地进行了测试。这是我的代码,它将执行循环查询,直到找到用户。如果你想要一个函数,你可以在它的基础上创建一个http触发器

import sys
import json
import logging
import requests
import msal

config = json.load(open(sys.argv[1]))
authorityName = ["<tenant_a>.onmicrosoft.com","<tenant_b>.onmicrosoft.com"]
username = "userone@<tenant_a>.onmicrosoft.com"

for domainName in authorityName:
    # Create a preferably long-lived app instance which maintains a token cache.
    print("==============:"+config["authority"]+domainName)
    app = msal.ConfidentialClientApplication(
        "<client_id>", authority="https://login.microsoftonline.com/"+domainName,
        client_credential="<client_secret>",
        )
        # The pattern to acquire a token looks like this.
    result = None

    # Firstly, looks up a token from cache
    # Since we are looking for token for the current app, NOT for an end user,
    # notice we give account parameter as None.
    result = app.acquire_token_silent(["https://graph.microsoft.com/.default"], account=None)

    if not result:
        result = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])

    if "access_token" in result:
        print("access token===:"+result['access_token'])
        # Calling graph using the access token
        graph_data = requests.get(  # Use token to call downstream service
            "https://graph.microsoft.com/v1.0/users/"+username,
            headers={'Authorization': 'Bearer ' + result['access_token']}, ).json()
        if "error" in graph_data:
            print("error===="+json.dumps(graph_data, indent=2))
        else:
            print(json.dumps(graph_data, indent=2))
            break

    else:
        print(result.get("error"))
        print(result.get("error_description"))
        print(result.get("correlation_id"))
导入系统 导入json 导入日志记录 导入请求 进口msal config=json.load(打开(sys.argv[1])) authorityName=[“.onmicrosoft.com”、“.onmicrosoft.com”] 用户名=”userone@.onmicrosoft.com" 对于authorityName中的域名: #创建一个最好是长寿命的应用程序实例,该实例维护令牌缓存。 打印(“================:”+config[“authority”]+域名) app=msal.secretentialclientapplication( “”,权限=”https://login.microsoftonline.com/“+域名, 客户_凭证=”, ) #获取令牌的模式如下所示。 结果=无 #首先,从缓存中查找令牌 #因为我们正在为当前应用寻找令牌,而不是为最终用户, #请注意,我们将account参数设置为None。 结果=app.acquire_token_silent([“https://graph.microsoft.com/.default“],帐户=无) 如果没有结果: 结果=应用程序。为\u客户端获取\u令牌(范围=[”https://graph.microsoft.com/.default"]) 如果结果中出现“访问令牌”: 打印(“访问令牌===:”+结果['access\u token']) #使用访问令牌调用图形 graph_data=requests.get(#使用令牌调用下游服务 "https://graph.microsoft.com/v1.0/users/“+用户名, headers={'Authorization':'Bearer'+result['access_token']},).json() 如果图形_数据中出现“错误”: 打印(“错误==”+json.dumps(图形数据,缩进=2)) 其他: 打印(json.dumps(图形数据,缩进=2)) 打破 其他: 打印(result.get(“错误”)) 打印(result.get(“错误描述”)) 打印(result.get(“correlation\u id”))

我假设您想要实现一个函数,调用
xxx.net?tenant=target\u tenant&user=user\u name
,然后它将返回用户信息。基本上,如果我们需要通过graph api收集用户信息,我们需要该租户中的azure ad应用程序,并通过该应用程序生成访问令牌,使用令牌我们可以获得用户信息。在您的需求中,您希望在不同的租户中收集信息,因此您需要在每个租户中创建ad应用程序(如果需要多个租户应用程序),并根据请求参数决定使用哪个应用程序。我在什么地方误解了吗?没错。例如,我们有一个名为test的用户,我们想了解有关该用户的信息,但是我们不知道该用户居住在哪个租户。因此,我们使用一个脚本遍历每个租户,然后返回结果。很抱歉,我对python不太熟悉。如果你有更多的问题,请随时更新这里。我的帖子可以帮助你吗?请让我知道它是否有效。如果你得到任何其他的解决方案,你也可以在这里发布,并将其标记为答案,以便它可以帮助其他人。提前感谢:)