首页 > 解决方案 > 如何在 .net 核心中对 Workday API 进行身份验证?

问题描述

我正在尝试从 .NET Core 中的 Azure Functions 连接到 Workday API (SOAP),但遇到了一些身份验证问题。

从我所见,问题出在使用身份验证而不是传输,所以我尝试使用自定义绑定,但看起来 .NET Core 还不支持它。

SecurityBindingElement sb = SecurityBindingElement.CreateUserNameOverTransportBindingElement();

sb.IncludeTimestamp = false;

const int lim = Int32.MaxValue;
var timeout = TimeSpan.FromMinutes(2);

var cb = new CustomBinding(
    sb,
    new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8)
    {
        ReaderQuotas = new XmlDictionaryReaderQuotas
        {
            MaxDepth = lim,
            MaxStringContentLength = lim,
            MaxArrayLength = lim,
            MaxBytesPerRead = lim,
            MaxNameTableCharCount = lim
        }
    },
    new HttpsTransportBindingElement
    {
        MaxReceivedMessageSize = lim,
        MaxBufferSize = lim,

    })
{
    SendTimeout = timeout,
    ReceiveTimeout = timeout
};

var client = new WorkDayAbsenceServiceReference.Absence_ManagementPortClient(cb, new EndpointAddress("https://wd3-impl-services1.workday.com/ccx/service/mytenant/Absence_Management/v33.0"));
client.ClientCredentials.UserName.UserName = "myusername";
client.ClientCredentials.UserName.Password = "mypassword";

var headers = new WorkDayAbsenceServiceReference.Workday_Common_HeaderType() {};

var requestType = new WorkDayAbsenceServiceReference.Get_Time_Off_Plan_Balances_RequestType()
{
    Request_Criteria = new WorkDayAbsenceServiceReference.Time_Off_Plan_Balance_Request_CriteriaType()
    {
        Employee_Reference = new WorkDayAbsenceServiceReference.WorkerObjectType()
        {
            ID = new WorkDayAbsenceServiceReference.WorkerObjectIDType[]
            {
                new WorkDayAbsenceServiceReference.WorkerObjectIDType
                {
                    type = "Employee_ID",
                    Value = "_0000028"
                }
            }
        }
    }
};


var test = await client.Get_Time_Off_Plan_BalancesAsync(headers, requestType);

我得到的错误代码:

System.Private.CoreLib:执行函数时出现异常:GetDaysOff。System.Private.ServiceModel:不支持 TransportSecurityBindingElement.BuildChannelFactoryCore。

标签: c#authenticationasp.net-coreazure-functionsworkday-api

解决方案


非常感谢Mohit Verma,在花了几个小时构建 SOAP 信封之后,我能够从 Workday API 获取日期。

我的代码使用 WSS 密码文本安全进行身份验证:

string uriBase = Environment.GetEnvironmentVariable("UriBaseWorkdayAbsenceManagement");
        string user = Environment.GetEnvironmentVariable("WorkdayUsername");
        string pass = Environment.GetEnvironmentVariable("WorkdayPassword");

        string xml;
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        using (MemoryStream ms = new MemoryStream())
        {
            using (XmlWriter writer = XmlWriter.Create(ms, settings))
            {
                XmlSerializerNamespaces names = new XmlSerializerNamespaces();
                names.Add("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
                names.Add("bsvc", "urn:com.workday/bsvc");
                XmlSerializer cs = new XmlSerializer(typeof(Envelope));
                var myEnv = new Envelope()
                {
                    Header = new EnvelopeHeader()
                    {
                        Security = new Security()
                        {
                            UsernameToken = new SecurityUsernameToken()
                            {
                                Username = user,
                                Password = new SecurityUsernameTokenPassword()
                                {
                                    Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText",//update type to match your case
                                    Value = pass
                                }
                            }
                        }
                    },
                    Body = new EnvelopeBody()
                    {
                        get_Time_Off_Plan_Balances_RequestType = new WorkDayAbsenceServiceReference.Get_Time_Off_Plan_Balances_RequestType()
                        {
                            Request_Criteria = new WorkDayAbsenceServiceReference.Time_Off_Plan_Balance_Request_CriteriaType()
                            {
                                Employee_Reference = new WorkDayAbsenceServiceReference.WorkerObjectType()
                                {
                                    ID = new WorkDayAbsenceServiceReference.WorkerObjectIDType[]
                                    {
                                        new WorkDayAbsenceServiceReference.WorkerObjectIDType
                                        {
                                            type = "Employee_ID",
                                            Value = workerId
                                        }
                                    }
                                }
                            }
                        }
                    }
                };


                cs.Serialize(writer, myEnv, names);
                ms.Flush();
                ms.Seek(0, SeekOrigin.Begin);
                StreamReader sr = new StreamReader(ms);
                xml = sr.ReadToEnd();
            }
        }

        SoapEnvelope responseEnvelope = null;
        using (var client = SoapClient.Prepare().WithHandler(new DelegatingSoapHandler()
        {
            OnHttpRequestAsyncAction = async (z, x, y) =>
            {
                x.Request.Content = new StringContent(xml, Encoding.UTF8, "text/xml");
            }
        }))
        {
            responseEnvelope = client.SendAsync(uriBase, "action", SoapEnvelope.Prepare()).Result;
        }

身体信封特定于我的情况。


推荐阅读