我需要使用用户名令牌来验证Primavera P6 Web服务。我在VS2010中创建了控制台应用程序,并添加了一个服务引用:
http://localhost:8206/p6ws/services/ExportService?wsdl
所以此刻我有一个代理类,我可以这样写:
var exportService = new ExportPortTypeClient();
var project = new ExportProject { ProjectObjectId = 1000 };
exportService.ExportProject(project);
当我尝试调用ExportProject()时,由于身份验证失败,我收到异常。
有没有人使用Username Token进行身份验证的示例代码?
答案 0 :(得分:2)
确保使用如下自定义绑定创建客户端:
var securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityElement.AllowInsecureTransport = true; //in case you don't use SSL
securityElement.EnableUnsecuredResponse = true; //in case you don't use SSL
var encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
var transportElement = new HttpTransportBindingElement();
var binding = new CustomBinding(securityElement, encodingElement, transportElement);
EndpointAddress endpointAddress = new EndpointAddress("<your endpoint to service goes here>");
var exportService = new ExportPortTypeClient(binding, endpointAddress);
var project = new ExportProject { ProjectObjectId = 1000 };
exportService.ExportProject(project);
答案 1 :(得分:0)
我终于找到了使用P6 WebServices的用户名令牌的解决方案。它并不像你想象的那么直截了当。您需要包含WSE标头。
此解决方案位于Rick Strahl's blog.
public class WebServiceClientFactory<T> : IWebServiceClientFactory<T> {
public WebServiceClientFactory() {
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 9999;
}
public T GetClient(Credentials cred) {
ChannelFactory<T> channelFactory = new ChannelFactory<T>(GetBinding(), new EndpointAddress(cred.Url));
channelFactory.Endpoint.Behaviors.Remove<System.ServiceModel.Description.ClientCredentials>();
channelFactory.Endpoint.Behaviors.Add(new CustomCredentials());
channelFactory.Endpoint.Behaviors.Add(new CustomP6DbInstanceBehavior(cred.DatabaseInstanceId));
channelFactory.Credentials.UserName.UserName = cred.Username;
channelFactory.Credentials.UserName.Password = cred.Password;
return channelFactory.CreateChannel();
}
private Binding GetBinding() {
var security = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
security.IncludeTimestamp = false;
var encoding = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
var transport = new HttpsTransportBindingElement {
MaxReceivedMessageSize = 20000000 // 20 megs
};
return new CustomBinding(security, encoding, transport);
}
}
我使用ChannelFactory创建客户端。
from scrapy.http import Request
from scrapy import Spider
import json
class edx_scraper(Spider):
name = "edxScraper"
start_urls = [
'https://www.edx.org/api/v1/catalog/search?selected_facets[]=content_type_exact%3Acourserun&selected_facets[]=language_exact%3ASpanish&page=1&page_size=9&partner=edx&hidden=0&content_type[]=courserun&content_type[]=program&featured_course_ids=course-v1%3AHarvardX+CS50B+Business%2Ccourse-v1%3AMicrosoft+DAT206x+1T2018%2Ccourse-v1%3ALinuxFoundationX+LFS171x+3T2017%2Ccourse-v1%3AHarvardX+HDS2825x+1T2018%2Ccourse-v1%3AMITx+6.00.1x+2T2017_2%2Ccourse-v1%3AWageningenX+NUTR101x+1T2018&featured_programs_uuids=452d5bbb-00a4-4cc9-99d7-d7dd43c2bece%2Cbef7201a-6f97-40ad-ad17-d5ea8be1eec8%2C9b729425-b524-4344-baaa-107abdee62c6%2Cfb8c5b14-f8d2-4ae1-a3ec-c7d4d6363e26%2Ca9cbdeb6-5fc0-44ef-97f7-9ed605a149db%2Cf977e7e8-6376-400f-aec6-84dcdb7e9c73'
]
def parse(self, response):
data = json.loads(response.text)
for course in data['objects']['results']:
url = 'https://www.edx.org/api/catalog/v2/courses/' + course['key']
yield response.follow(url, self.course_parse)
if 'next' in data['objects'] is not None:
yield response.follow(data['objects']['next'], self.parse)
def course_parse(self, response):
course = json.loads(response.text)
yield{
'name': course['title'],
'effort': course['effort'],
}