如何在C#中使用用户名令牌验证Primavera P6 Web服务?

时间:2013-07-29 14:46:41

标签: c# wcf primavera

我需要使用用户名令牌来验证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进行身份验证的示例代码?

2 个答案:

答案 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'],
    }