在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