ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

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

2019-07-05 23:57:39  阅读:295  来源: 互联网

标签:python postgresql proxy django microsoft-dynamics


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

技术

> 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有