在PostgreSQL和Dynamics 365 Web API之间构建Python3身份验证代理服务器

2024-05-20 19:35:30 发布

您现在位置:Python中文网/ 问答频道 /正文

几天之后,我就要把这个项目的一些知识和技能结合起来。我很感激任何能帮助我的人。在

技术

问题

  • CRM拥有最新的客户数据,并希望将其引入PostgreSQL以用于许多事情
  • 想要使用www_fdw,因为它是我见过的唯一一个可以使用webapi的外部数据包装器:https://github.com/cyga/www_fdw/wiki
  • Dynamics Web API使用OAuth2,www_fdw本机不支持任何类型的身份验证
  • www_fdw的开发人员交谈,他建议创建一个代理服务器来处理与Microsoft的OAuth2身份验证
  • 带有www_fdw的PostgreSQL将与代理进行通信,代理将向Microsoft发送身份验证,从而使其能够将Web API视为外部表,以便将其视为任何其他表

这三个部分以及迄今为止所做的尝试

三部分=www_fdw+代理服务器+OAuth2

  1. www_fdw:基于此,我使用了以下参数进行设置:https://github.com/cyga/www_fdw/wiki/Examples

    DROP EXTENSION IF EXISTS www_fdw CASCADE;
    CREATE EXTENSION www_fdw;
    CREATE SERVER crm FOREIGN DATA WRAPPER www_fdw OPTIONS
        (uri 'http://localhost:12345');  -- proxy server
    CREATE USER MAPPING FOR current_user SERVER crm;
    
    -- for testing trying to get 'name' out of the CRM 'accounts' table and
       naming the foreign table the same as the table in CRM
    CREATE FOREIGN TABLE accounts (
        name varchar(255)
    ) SERVER crm;
    
  2. crmproxytest.py对于代理服务器,我一直在尝试使用以下链接创建一个简单的服务器:http://effbot.org/librarybook/simplehttpserver.htm

    ^{pr2}$

    这看起来就像控制台上的serving at port 12345一样工作,显示正在运行nmap -sT -O localhost,当{}运行时,控制台上有一些活动在运行服务器。否则就不能从中得到任何活动。在

    从PostgreSQL运行SELECT * FROM accounts会导致Can't get a response from server: Failed to connect to ::1: Permission denied

  3. OAuth2。我把crm.py放在一起,在和微软谈过之后,整理了他们的文档,找到了这个链接:http://alexanderdevelopment.net/post/2016/11/27/dynamics-365-and-python-integration-using-the-web-api/

    简而言之,你必须向azureactivedirectory注册你的应用,这样你就可以得到一个client_idclient_secret,此外还可以获得OAuth 2.0 Token URI和{}。然后,您可以向authorizationendpoint发送一个请求,如果凭证匹配,它将返回一个令牌,然后将令牌发送给tokenendpoint,并最终授予对Web API的访问权。在

    这是我最后使用的代码,从Dynamics Web API检索数据,并将其填充到控制台中:

    import requests  
    import json
    
    #set these values to retrieve the oauth token
    crmorg = 'https://ORG.crm.dynamics.com' #base url for crm org  
    clientid = '00000000-0000-0000-0000-000000000000' #application client id  
    client_secret = 'SUPERSECRET'
    username = 'asd@asd.com' #username  
    userpassword = 'qwerty' #password
    authorizationendpoint =  'https://login.windows.net/ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ/oauth2/authorize'
    tokenendpoint = 'https://login.windows.net/ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ/oauth2/token' #oauth token endpoint
    
    #set these values to query your crm data
    crmwebapi = 'https://ORG.api.crm.dynamics.com/api/data/v8.2' #full path to web api endpoint  
    crmwebapiquery = '/accounts?$select=name&$orderby=name' #web api query (include leading /)
    
    #build the authorization token request
    tokenpost = {  
        'client_id':clientid,
        'client_secret': client_secret,
        'resource':crmorg,
        'oauthUrl': authorizationendpoint,
        'username':username,
        'password':userpassword,
        'grant_type':'password'
        }
    
    #make the token request
    tokenres = requests.post(tokenendpoint, data=tokenpost)
    
    #check the value of tokenres
    print(tokenres)
    
    #set accesstoken variable to empty string
    accesstoken = ''
    
    #extract the access token
    try:  
        accesstoken = tokenres.json()['access_token']
    except(KeyError):  
        #handle any missing key errors
        print('Could not get access token')
    
    # check point for debugging
    # print(accesstoken)
    
    #if we have an accesstoken
    if(accesstoken!=''):  
        #prepare the crm request headers
        crmrequestheaders = {
            'Authorization': 'Bearer ' + accesstoken,
            'OData-MaxVersion': '4.0',
            'OData-Version': '4.0',
            'Accept': 'application/json',
            'Content-Type': 'application/json; charset=utf-8',
            'Prefer': 'odata.maxpagesize=500',
            'Prefer': 'odata.include-annotations=OData.Community.Display.V1.FormattedValue'
            }
    
        #make the crm request
        crmres = requests.get(crmwebapi+crmwebapiquery, headers=crmrequestheaders)
    
        try:
            #get the response json
            crmresults = crmres.json()
    
            #loop through it
            for x in crmresults['value']:
                # print (x['fullname'] + ' - ' + x['contactid'])
                print (x['name'])
        except KeyError:
            #handle any missing key errors
            print('Could not parse CRM results')
    

    这就像一个咒语,但实际上是为了测试OAuth2。变量crmwebapi和{}组合的查询实际上不需要在其中,因为PostgreSQL如果FDW正常工作,应该允许对webapi运行SQL查询。

不管怎样,我希望我解释得足够好。似乎我得到了三个独立的拼图,或者说是一种工作,但是把它们放在一起是我的困难所在。crm.py和{}可能需要组合,但不确定如何组合。在

提前感谢您的帮助!在

编辑:显然到处都是www_ftw,而不是{}。在


Tags: thetohttpscomclienttokenwebjson
1条回答
网友
1楼 · 发布于 2024-05-20 19:35:30

我觉得在第一步中设置FDW没问题。在

步骤2中的Python脚本需要在顶部使用shebang。否则它将被视为bash,因此前3行运行^{},并将屏幕截图保存到名为http.serversocketserver和{}的新文件中。这会使脚本在PORT行死亡之前忙碌一段时间。同时(甚至在它死后),只运行curl http://localhost:12345会产生与Postgres相同的错误:

curl: (7) Failed to connect to localhost port 12345: Connection refused

添加#!/usr/bin/env python3后,脚本将响应请求。例如,我可以说curl http://localhost:12345/etc/passwd并得到一个结果。在

我不确定您打算如何连接步骤3(OAuth),但希望这个答案能让您克服目前阻碍您的因素。在

相关问题 更多 >