Wanting to communicate with a SOAP webservice, I had C# classes created by SvcUtil.exe from the wsdl file.
When sending the Request below to a secure server (HTTPS with BASIC auth) I receive a System.ServiceModel.Security.MessageSecurityException and when checking the HTTP request by having traffic go though a Burp proxy I see that no BASIC auth information is passed. Is anything missing for the SOAP request in the C# code or what could be the problem that the BASIC auth does not work?
var binding = new WSHttpBinding();
binding.MessageEncoding = WSMessageEncoding.Mtom;
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.Name = "BasicAuthSecured";
SearchServicePortClient searchClient = new SearchServicePortClient(binding, new EndpointAddress("https://myUrl:Port/myService"));
searchClient.ClientCredentials.UserName.UserName = "username";
searchClient.ClientCredentials.UserName.Password = "pw";
query soap = new query();
//...
queryResponse response = searchClient.query(soap);
Thanks in advance
This is another approach, don't know if it is the best though
using (var client = _clientFactory.GetClient())
{
var credentials = Utils.EncodeTo64("user123:password");
client.ChannelFactory.CreateChannel();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
//operation
client.Send(request);
}
}
Try to use TransportWithMessageCredential:
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
Related
I'm experiencing an intermittent problem with our SharePoint 2010 REST API. I have a .Net Core Console application that makes a series of calls to SharePoint List Endpoints to get a JSON response. My problem is that at random times, the API response is an error page:
A relative URI cannot be created because the 'uriString' parameter
represents an absolute URI.http://www.example.com/somefolder/file.svc
Is there a problem with my HTTPClient configuration? Is there a configuration setting that I can toggle in SharePoint to prevent the error or more reliable?
var uri = new Uri("http://www.example.com/");
var credential = new NetworkCredential("username", "password", "domain");
var credentialsCache = new CredentialCache { { uri, "NTLM", credential } };
var handler = new HttpClientHandler { Credentials = credentialsCache };
HttpClient Client = new HttpClient(handler);
Client.BaseAddress = new Uri("http://www.example.com/sharepoint/path/ListData.svc/");
// Make the list request
var result = await Client.GetAsync("MySharePointList");
To get the list items, the REST API URI like below.
http://sp2010/_vti_bin/ListData.svc/listname
Modify the code as below.
var siteUrl = "http://www.example.com/";
var listName = "MySharePointList";
var uri = new Uri(siteUrl);
var credential = new NetworkCredential("username", "password", "domain");
var credentialsCache = new CredentialCache { { uri, "NTLM", credential } };
var handler = new HttpClientHandler { Credentials = credentialsCache };
HttpClient client = new HttpClient(handler);
client.BaseAddress = new Uri(uri, "/_vti_bin/ListData.svc");
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("ContentType", "application/json;odata=verbose");
var requestURL = siteUrl + "/_vti_bin/ListData.svc/" + listName;
// Make the list request
var result = client.GetAsync(requestURL).Result;
var items= result.Content.ReadAsStringAsync();
Below is code in c# to get token from server.
The code in C# is working fine and I am able to receive the token from server but when I write same syntax in VB.net then I get exception.
The framework for the code is same "4.6.2". App config of both the code are same.
var sEndPointAddress = "url";
WS2007HttpBinding binding = new WS2007HttpBinding();
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress("https://IPAddress/adfs/services/trust/13/usernamemixed"));
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
trustChannelFactory.Credentials.UserName.UserName = "username";
trustChannelFactory.Credentials.UserName.Password = "password";
RequestSecurityToken requestToken = new RequestSecurityToken(RequestTypes.Issue);
requestToken.AppliesTo = new EndpointReference(sEndPointAddress);
WSTrustChannel tokenClient = (WSTrustChannel)trustChannelFactory.CreateChannel();
var token = tokenClient.Issue(requestToken);
I have converted the same code in VB.Net but I am receving exception error.
The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.
Below is code in VB.Net
Dim sEndPointAddress As String = "url"
Dim binding As New WS2007HttpBinding()
binding.Security.Message.EstablishSecurityContext = False
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName
binding.Security.Mode = SecurityMode.TransportWithMessageCredential
Dim trustChannelFactory As New WSTrustChannelFactory(binding, New EndpointAddress("https://IPAddress/adfs/services/trust/13/usernamemixed"))
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13
trustChannelFactory.Credentials.UserName.UserName = "username"
trustChannelFactory.Credentials.UserName.Password = "password"
Dim requestToken As New RequestSecurityToken(RequestTypes.Issue)
requestToken.AppliesTo = New EndpointReference(sEndPointAddress)
Dim tokenClient As WSTrustChannel = CType(trustChannelFactory.CreateChannel(), WSTrustChannel)
Dim token As Object = tokenClient.Issue(requestToken)
Below is the code I'm using to request "Symmetric" token type from Adfs and I receive the error as mentioned in the title.
A quick google search points out that, it is because of the absence of token signing certificate but I do have it defined in the Adfs.
Do I need to explicitly assign it to "Relying party" or having it in ADFS 2.0 works?
Please can anybody point me to right direction or have somebody knows step to associate token signing certificate to relying party if it is required?
WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.EstablishSecurityContext = false;
binding.BypassProxyOnLocal = true;
binding.UseDefaultWebProxy = true;
System.ServiceModel.Security.WSTrustChannelFactory factory = new System.ServiceModel.Security.WSTrustChannelFactory(
binding, new EndpointAddress(userNameMixedRequest.GetUserNameMixedUrl));
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.SupportInteractive = false;
factory.Credentials.UserName.UserName = "domain\username"
factory.Credentials.UserName.Password = "password"
System.IdentityModel.Protocols.WSTrust.RequestSecurityToken request = new System.IdentityModel.Protocols.WSTrust.RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(userNameMixedRequest.ClientUri),
KeyType = KeyTypes.Symmetric
};
System.ServiceModel.Security.IWSTrustChannelContract channel = factory.CreateChannel();
channel.Issue(request)
I'm supporting a project where we recently needed to apply a series of upgrades to a newer version of the .Net Framework. This has largely succeeded but for one final component that's been around for a very long time.
Our client uses InfoPath templates to populate information for other users to consume. Everything the templates need comes from a WCF web service we host. We set the web service call up with the following code.
private WSHttpBinding CreateBinding()
{
var wsHttpBinding = new WSHttpBinding();
wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.BypassProxyOnLocal = false;
wsHttpBinding.TransactionFlow = false;
wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
wsHttpBinding.MaxBufferPoolSize = 524288;
wsHttpBinding.MaxReceivedMessageSize = 2147483647;
wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
wsHttpBinding.TextEncoding = Encoding.UTF8;
wsHttpBinding.UseDefaultWebProxy = true;
wsHttpBinding.AllowCookies = false;
wsHttpBinding.ReaderQuotas.MaxDepth = 32;
wsHttpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384;
wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096;
wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;
wsHttpBinding.ReliableSession.Ordered = true;
wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.ReliableSession.Enabled = false;
wsHttpBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
wsHttpBinding.Security.Transport.Realm = string.Empty;
wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
wsHttpBinding.Security.Message.NegotiateServiceCredential = false;
wsHttpBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256;
return wsHttpBinding;
}
private EndpointAddress CreateEndPoint()
{
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 certificate = store.Certificates.Find(X509FindType.FindBySubjectName, "*.wildcard.address.foo", false)[0];
store.Close();
EndpointIdentity identity = EndpointIdentity.CreateX509CertificateIdentity(certificate);
string address = getWcfServiceUrl();
AddressHeader header = AddressHeader.CreateAddressHeader(address);
List<AddressHeader> headerList = new List<AddressHeader> { header };
Uri uri = new Uri(address);
var endpointAddress = new EndpointAddress(uri, identity, headerList.ToArray());
return endpointAddress;
}
}
This works fine and if we're testing it out, calls can be made successfully for all other intents and purposes. Except for one.
In one case we need to get information from a 3rd party resource. In that situation, our web service makes a separate call out to this 3rd party at an HTTPS address (passed in to the url parameter here:
private string requestURL(string url)
{
string toReturn = null;
Stream stream = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = httpMethod;
stream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
StreamReader reader = new StreamReader(stream);
toReturn = reader.ReadToEnd();
}
catch(Exception e)
{
throw new Exception("Error with that service please try again: " + e.Message, e);
}
finally
{
if(stream != null)
{
stream.Close();
}
}
return toReturn;
}
In this case, the following error is returned:
The request was aborted: Could not create SSL/TLS secure channel.
My suspicion is that we're setting up a very specific set of constraints around the SSL connection between our local client (i.e. InfoPath) and the web service but the call from that web service to the 3rd party is not set up with any constraints beyond simply calling over HTTPS.
What should I be looking out for in trying to fix this issue?
WCF IMHO is particular about configuration at both ends and asks for things like transport credential specifically in the back and forth. I suspect you have no control of how the security is managed at the third party and can't change it, but your generic method to call all web services won't work because the configuration doesn't match.
I get server error when I trying connect to webService. Do you know why?
Error
{System.Collections.Generic.SynchronizedReadOnlyCollection}
Code
BasicHttpBinding basicbinding = new BasicHttpBinding();
basicbinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
basicbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicbinding.Name = "HTTP_Port";
WSPI.InvoiceCheck_OutClient invoiceCheck_OC = new WSPI.InvoiceCheck_OutClient(basicbinding, new EndpointAddress(new Uri("http://example.example.eu:51200/XISOAPAdapter/MessageServlet?senderParty=&")));
invoiceCheck_OC.ClientCredentials.UserName.UserName = "Login";
invoiceCheck_OC.ClientCredentials.UserName.Password = "Password";
WSPI.InvoiceCheck invoiceCheck = new WSPI.InvoiceCheck();
WSPI.InvoiceCheck_OutRequest invoiceCheck_OR = new WSPI.InvoiceCheck_OutRequest();
WSPI.InvoiceConfirm invoiceCheck_IC = new WSPI.InvoiceConfirm();
invoiceCheck.InvoiceNo = "1000000";
invoiceCheck.IssueDate = "2014-01-01";
invoiceCheck.VatNo = "88090302342";
invoiceCheck.Username = "SuperRafal";
string response = invoiceCheck_OC.InvoiceCheck_Out(invoiceCheck).Response.ToString();
Code working correct there was a problem with link :) Sorry