数据库
首页 > 数据库> > 在PostgreSQL和Dynamics 365 Web API之间构建Python3 auth代理服务器

在PostgreSQL和Dynamics 365 Web API之间构建Python3 auth代理服务器

作者:互联网

经过几天的一些进步,我接受了我缺乏知识或技能水平的事实,将所有这些部分组合在一起并完成了这个项目.因此,我对任何可以帮助我解决这个问题的人表示欢迎和感激.

技术

> CentOS 7.5
> Python 3.6.0
> Django 1.10.5
> PostreSQL 9.2
> Microsoft CRM Dynamics 365 online,具有最新的客户端数据,因此必须使用Web API:https://msdn.microsoft.com/en-us/library/gg334767.aspx

问题

> CRM拥有最新的客户端数据,并希望将其引入PostgreSQL以用于众多事情
>想要使用www_fdw,因为它是我见过的PostgreSQL唯一可以使用Web API的外部数据包装器: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

> 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;

> crmproxytest.py代理服务器,我一直试图使用此链接制作一个简单的骨头:http://effbot.org/librarybook/simplehttpserver.htm

import socketserver
import http.server
import urllib

PORT = 12345

class Proxy(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        self.copyfile(urllib.urlopen(self.path), self.wfile)

httpd = socketserver.ForkingTCPServer(('', PORT), Proxy)
print ("serving at port", PORT)
httpd.serve_forever()

这似乎工作,因为它说在服务器上的端口12345上运行,显示运行nmap -sT -O localhost,运行nmap时运行服务器的控制台上有一些活动.否则无法从中获得任何活动.

从PostgreSQL运行SELECT * FROM帐户导致无法从服务器获取响应:无法连接到:: 1:权限被拒绝.
> OAuth2.我把crm.py放在一起,并在与微软交谈后对其进行了工作,整理了他们的文档,并找到了这个链接:http://alexanderdevelopment.net/post/2016/11/27/dynamics-365-and-python-integration-using-the-web-api/

简而言之,您必须向Azure Active Directory注册您的应用程序,以便除了能够获取OAuth 2.0令牌URI和OAuth 2.0授权URI之外,还可以获得client_id,client_secret.然后,您可以向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和crmwebapiquery的查询实际上不需要在那里,因为PostgreSQL,如果FDW工作正常,应该允许对Web API运行SQL查询.

无论如何,我希望我能够很好地解释这一切.似乎我有三个独立的拼图工作或工作,但把它们放在一起是我被卡住的地方. crm.py和crmtest.py可能需要合并,但不确定如何.

在此先感谢您的帮助!

编辑:显然有www_ftw到处而不是www_fdw.

解决方法:

在步骤1中设置FDW对我来说没问题.

您在步骤2中的Python脚本需要顶部的shebang.否则它被视为bash,因此前3行运行import(1)并将屏幕截图保存到名为http.server,socketserver和urllib的新文件中.这使得脚本在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),但希望这个答案会让你超越现在阻挡你的东西.

标签:python,postgresql,proxy,django,microsoft-dynamics
来源: https://codeday.me/bug/20190705/1391961.html