【问题标题】:Microsoft Graph Authentication微软图形身份验证
【发布时间】:2018-01-17 23:41:11
【问题描述】:

我正在用 Python 构建一个可以从 Azure AD 检索数据的应用程序。此数据可能需要应用程序权限或委托权限。我成功检索了只需要应用程序权限的数据。但是,为了检索需要委托权限的数据,我正在尝试使用 OAuth2。是否可以使用 OAuth2 通过 Microsoft Graph 进行身份验证,但不让用户使用网页登录,而是通过 Python 脚本本身提供用户凭据?

注意:我想使用 Microsoft Graph API(v1.0 和 beta)而不是 Azure AD Graph API。

【问题讨论】:

  • @ShawnTabrizi 这是另一种情况。我正在尝试对 Graph API(v1.0 和 beta)而不是 Azure AD API 进行身份验证。另外,我正在寻找 Python 中的东西。
  • 无论您尝试向哪个端点进行身份验证,您正在寻找的流程是资源所有者密码凭据,并且您可能需要使用纯 REST 调用来实现这一点,即记录在案。
  • @ShawnTabrizi 也是用 C# 编写的,我对此几乎一无所知:(
  • @Raj,这里有一些对 Microsoft Graph 进行 Python 身份验证的选项,可能会有所帮助:github.com/microsoftgraph/python-sample-auth/blob/master/…

标签: python azure oauth-2.0 azure-active-directory azure-ad-graph-api


【解决方案1】:

您需要一个 Azure AD 应用程序才能使用 Graph API 进行身份验证。本机 Azure AD 应用以及此处描述的流程和注意事项适用于 ADAL.net。我用它来配置 Microsoft Teams 无人值守:http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/

我猜对于 Python,你应该看看 ADAL for Python:https://github.com/introp-software/azure-activedirectory-library-for-python-old/blob/master/README.md

我认为用户名/密码身份验证仅适用于本机 Azure AD 应用,而不适用于 web/web api 类型。

【讨论】:

    【解决方案2】:

    是的,这是可能的 - 但请记住,有两个 Azure AD 端点用于应用程序注册!

    尝试在 AAD V2.0 端点 (apps.dev.microsoft.com) 上注册应用程序,然后在您的请求中使用“密码”grant_type。

    以下是您需要的步骤:

    • 在 AAD v2.0 端点上注册您的应用,并生成密码(取 请注意)
    • 分配您所需的权限(在本例中为委托)
    • 作为回调 URL,我建议首先使用邮递员的 Oauth2 回调 URL,这样您就可以调试您正在执行的操作:https://www.getpostman.com/oauth2/callback
    • 重要!如果这些权限中的任何一个需要管理员同意,您必须首先同意他们才能使应用程序可用。这需要管理员用户登录一次。

    获得同意后,您的请求需要满足以下条件才能获得不记名令牌作为原型:

        POST https://login.microsoftonline.com/common/oauth2/token
        Request body (application/x-www-form-urlencoded): 
        grant_type=[password]
        username=[user email address]
        password=[user password]
        resource=https://graph.microsoft.com
        client_id=[your newly registered application ID] 
        client_secret=[application password you noted during registration] 
    

    如果成功,您将获得不记名和刷新令牌作为响应。

    希望这会有所帮助,

    【讨论】:

      【解决方案3】:

      假设您已注册并配置(api 权限)您的天蓝色应用程序,并且您已复制应用程序“客户端 ID”和“客户端密码”,您可以定义一个保存会话的类。 以下代码适用于我的应用:

      import json
      import requests
      from requests_oauthlib import OAuth2Session
      from oauthlib.oauth2 import BackendApplicationClient
      
      
      class SharepointSession(object):
          """ Base Class without credentials, use real credentials in derived Classes
          or instances
          """
          api_uri = "https://graph.microsoft.com"
          api_version = "v1.0"
          scope = ["https://graph.microsoft.com/.default"]
          directory_id = ""  # - tenant id
          token_url = "https://login.microsoftonline.com/{}/oauth2/v2.0/token"
          sites_url = "{}/{}/sites".format(api_uri, api_version)
          site = document_name = app_name = client_id = client_secret = ""
          site_id = None
          doc_id = None
      
          def __init__(self):
              """  """
      
          def getTokenizedSession(self):
              """
              OAuth2 to get access token
              First set up a backend client, mind to set grant_type
              build a OAuth2 Session with the client
              get access token
      
              Mind: python 3.x oauthlib requires scope params on more calls than py 2.x
              """
              client = BackendApplicationClient(
                  client_id=self.client_id, scope=self.scope, grant_type="client_credentials")
      
              session = OAuth2Session(client=client, scope=self.scope)
              # fill access token
              token = session.fetch_token(token_url=self.token_url.format(self.directory_id),
                                          client_id=self.client_id,
                                          scope=self.scope,
                                          client_secret=self.client_secret)
              self.session = session
              self.token = token
              return session, token
      
          def getSiteId(self):
              # get the site id
              ae = "{}/myonline.sharepoint.com:/sites/{}:".format(
                  self.sites_url, self.site)
              rt = self.session.get(ae)
              response = json.loads(rt.text)
              self.site_id = response.get("id")
              return self.site_id
      
          def someOtherMethod(self):
              """         ...             """
      

      现在您可以使用从您的 azure 应用注册复制的凭据实例化会话类,即“目录 ID”(与租户 ID 相同)、“客户端 ID”和“客户端密码” 像这样:

      mysp_session = SharepointSession()
      mysp_session.directory_id = "XXXXXXXX-XXXX-YYYY-ZZZZ-XXXXXXXXX"
      mysp_session.site = "MySitename"
      mysp_session.document_name = "Testlist"
      mysp_session.client_id = r"xxxxxxxxxxxxxxxxxxxxxxx"
      mysp_session.client_secret = r"xxxxxxxxxxxxxxxxxxxxxxx"
      
      # connect 
      session, token = mysp_session.getTokenizedSession()
      
      # do your business logic
      mysp_session.getSiteId()
      ....
      mysp_session.someOtherMethod()
      

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-25
        • 1970-01-01
        • 2023-03-03
        相关资源
        最近更新 更多