I'm trying to connect to Workday API (SOAP) from Azure Functions in .NET Core, but I'm encountering some issues with authentication.
From what I've seen, the problem comes from using authentication over transport, so I tried to use custom bindings but looks like .NET Core doesn't support it yet.
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);
And the error code I get :
System.Private.CoreLib: Exception while executing function: GetDaysOff. System.Private.ServiceModel: TransportSecurityBindingElement.BuildChannelFactoryCore is not supported.
Message feature in security is not yet supported in asp.net core-2.0.
You can check a full list of supported feature here: https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFeatures-v2.0.0.md
Alternatively you can try to create your own SOAP envelope kind of a Web api build on .Net Standard which will do security stuff for you and you can simple call it from your Azure function using httpclient. I haven't tried it but i got this idea from below post:
How Do I Call XML SOAP Service that Requires Signature from .Net Core?
private static HttpClient Client = new HttpClient();
Uri uri = new Uri("https://thirdparty.com/service.svc");
X509Certificate2 cert = // from some store etc
var envelope = BuildEnvelope(cert);
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri))
{
request.Content = new StringContent(envelope, Encoding.UTF8, "application/soap+xml");
using (HttpResponseMessage response = Client.SendAsync(request).Result)
{
if (response.IsSuccessStatusCode)
{
response.Content.ReadAsStringAsync().ContinueWith(task =>
{
string thirdparty_envelope = task.Result;
XElement thirdparty_root = XElement.Parse(thirdparty_envelope);
// etc
}, TaskContinuationOptions.ExecuteSynchronously);
}
}
}
Additional reference:
https://github.com/dotnet/wcf/issues/13
https://github.com/dotnet/wcf/issues/8
Alternatively, you can use Microsoft Logic app with Workday connector and then you can use the endpoint. Though it's in preview, but you can implement your custom connector as well.
Hope it helps, Feel free to tag me in your conversation.