在PostgreSQL和Dynamics 365 Web API之间构建Python3身份验证代理服务器
经过几天的进步,我逐渐认识到,我缺乏知识或技能水平,无法把所有这些东西组合起来完成这个项目。因此,我呼吁并感谢任何能够帮助我解决这一问题的人 技术在PostgreSQL和Dynamics 365 Web API之间构建Python3身份验证代理服务器,python,django,postgresql,proxy,microsoft-dynamics,Python,Django,Postgresql,Proxy,Microsoft Dynamics,经过几天的进步,我逐渐认识到,我缺乏知识或技能水平,无法把所有这些东西组合起来完成这个项目。因此,我呼吁并感谢任何能够帮助我解决这一问题的人 技术 CentOS 7.5 Python 3.6.0 Django 1.10.5 PostResql9.2 Microsoft CRM Dynamics 365 online拥有最新的客户端数据,因此必须使用Web API: 问题 CRM中包含最新的客户机数据,并希望将其引入PostgreSQL以用于多种用途 想要使用www_fdw,因为它是我见过的
- CentOS 7.5
- Python 3.6.0
- Django 1.10.5
- PostResql9.2
- Microsoft CRM Dynamics 365 online拥有最新的客户端数据,因此必须使用Web API:
- CRM中包含最新的客户机数据,并希望将其引入PostgreSQL以用于多种用途
- 想要使用
,因为它是我见过的唯一一个可以使用Web API的PostgreSQL外部数据包装器:www_fdw
- Dynamics Web API使用OAuth2,并且
不支持任何类型的本机身份验证www_fdw
- 与
的开发人员交谈,他们建议使用代理服务器来处理与Microsoft的OAuth2身份验证www_fdw
- 带有
的PostgreSQL将与代理进行对话,代理将向Microsoft发送身份验证,最终能够将Web API视为外来表,从而将其视为任何其他表www_fdw
www_fdw
+代理服务器+OAuth2
www_fdw
:基于此,我使用以下参数进行设置:
crmproxytest.py
对于代理服务器,我一直在尝试使用以下链接创建一个简单的代理服务器:
这看起来像是控制台上的端口12345服务,显示运行nmap-sT-O localhost
,当运行nmap
时,控制台上运行服务器的一些活动。否则就无法从中获得任何活动
从PostgreSQL运行SELECT*FROM accounts
会导致无法从服务器获得响应:无法连接到::1:权限被拒绝
crm.py
,在与Microsoft交谈、整理了他们的文档并找到了以下链接后,它开始工作:
简而言之,除了能够获得OAuth 2.0令牌URI
和OAuth 2.0授权URI
之外,您还必须在Azure Active Directory中注册应用程序,以便获得client\u id
,client\u secret
。然后,您可以向授权端点
发送请求,如果凭据匹配,则会返回令牌,然后将令牌发送到令牌端点
,并最终授予对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\u ftw
,而不是www\u fdw
在步骤1中设置fdw对我来说似乎没问题
步骤2中的Python脚本顶部需要一个shebang。否则它将被视为bash,因此前3行将运行并将屏幕截图保存到名为http.server
、socketserver
和urllib
的新文件中。这会使脚本在端口
行上停止之前忙碌一段时间。同时(甚至在它死后),只运行curlhttp://localhost:12345
给出与Postgres相同的错误:
curl: (7) Failed to connect to localhost port 12345: Connection refused
添加#后/usr/bin/env python3
您的脚本将响应请求。例如,我可以说curlhttp://localhost:12345/etc/passwd
并获得结果
我不确定您打算如何连接第3步(OAuth),但希望这个答案能帮助您克服目前的障碍。嗨,保罗,我将按照您今天上午的建议进行操作。我认为目前最大的问题是将第2步和第3步结合在一起:设置一个Postgres可以与之对话的持久化进程,该进程将授权传递给Microsoft的OAuth2,以便它可以使用外部数据包装器查询Dynamics CRM Web API。@sockpuppet Paul的回答有帮助吗?如果是这样,请确保您接受它或添加注释,解释为什么这不是一个解决方案。
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')
curl: (7) Failed to connect to localhost port 12345: Connection refused