spa 和服务帐户 msal 使用什么授权流程

What auth flow to use with spa and service account msal

Microsoft 文档中有太多不同的流程,我不知道我需要哪一个。我正在使用 React 和 Python。 (我理解节点,所以如果有人解释使用 node/express 没问题)

用户应该看到的内容: 一个带有登录按钮的页面,导航在那里,但在登录之前不会工作。登录创建一个弹出窗口以使用 Microsoft 帐户登录。登录后,用户将能够使用导航查看动态信息。

我想做什么: 此应用程序需要登录用户并通过 'https://graph.microsoft.com/v1.0/me' 获取用户电子邮件。(不需要客户端机密)然后我需要在此请求中发送该电子邮件;

(承租人== {公司}。crm.dynamics.com。)

 allInfo = requests.get(
            f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()

此后端请求需要有客户端密码才能获取信息。所以我相信我的后端也需要登录到服务帐户。我认为我需要为我的后端获取令牌以代表服务帐户发出请求。

我有: 我有一个 React 前端,它正在登录用户并正确调用 'https://graph.microsoft.com/v1.0/me' 并收到该电子邮件。收到电子邮件后,我会将其发送到我的后端。

现在我不知道如何继续并且尝试了很多东西。

我对后端的尝试: 尝试 1:我得到一个令牌,但出现错误:{'error': {'code': '0x80072560', 'message': 'The user is not a member of the organization.'}}。问题是,这个 ID 是 Azure AD ID。它应该定义工作

@app.route('/dynToken', methods=['POST'])
def get_dyn_token():
    req = request.get_json()
    partnerEmail = req['partnerEmail']
    token = req['accessToken']
    body = {
        "client_id": microsoft_client_id,
        "client_secret": client_secret,
        "grant_type": "client_credentials",
        "scope": SCOPE_DYN,
    }
    TENANTID = '{hash here}'
    res = requests.post(
        f'https://login.microsoftonline.com/{TENANTID}/oauth2/v2.0/token', data=body).json()

    dyn_token = res['access_token']

    headers = {
        "Prefer": "odata.include-annotations=\"*\"",
        "content-type": "application/json; odata.metadata=full",
        "Authorization": f"Bearer {dyn_token}"
    }
    try:
        allInfo = requests.get(
            f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()
        print(allInfo)

尝试 2: 相同的代码,但不是 f'https://login.microsoftonline.com/{TENANTID}/oauth2/v2.0/token' 它 f'https://login.microsoftonline.com/common/oauth2/v2.0/token'。错误:发生异常:[Errno 期望值]:0。因为它 returns 一个空字符串。

现在我不知道我是否走在正确的道路上或去向何方。我知道如果令牌正确,路由会自行运行。我只使用了没有反应的 SSR,这些路线有效。但我也需要 React 在那里。我只是不知道在这里使用什么流程来获得我需要的东西。这些文档使 /me 路由工作变得容易。但是 {company}crm.dynamics.com 文档并没有真正提供我想要做的事情。

评论后的附加信息:

什么 'f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq '{email}'', headers=headers"正在尝试获取 API 键。完整代码:

 try:
        allInfo = requests.get(
            f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()

        partner_value = allInfo['value'][0]['_company_partner_value']

        response = requests.get(
            f'https://{TENANT}api/data/v9.0/company_partnerses({partner_value})', headers=headers).json()

        return {'key': response['company_apikey'], 'secret': response['company_apisecret']}

然后一旦它有了密钥:

def api_authentication(apikey, apisecret):
    headers = get_headers() #<-- same headers as above with using dyn_token 
    response = requests.get(
        f'https://{TENANT}api/data/v9.0/company_partnerses?$filter=company_apikey eq \'{apikey}\' and company_apisecret eq \'{apisecret}\'&$select=company_apikey,company_apisecret,_company_account_value,_company_primarycontact_value,blahblah_unassignedhours,company_reporturl', headers=headers).json()
    return response

之后,我能够获得我正在寻找的所有信息,并将其发送回我的前端以供客户查看。 (通过使用这些密钥向 crm 发出多个请求)

如果 CRM 信任颁发给客户端(您的 python 后端)的令牌,您正在使用的 client_credentials 授权应该有效。请使用 MSAL 库,而不是手工制作令牌请求。它将节省您的时间并消除错误。