I am trying to create a REST Client proxy programatically in C# using the code below but I keep getting a CommunicationException error. Am I missing something?
public static class WebProxyFactory
{
public static T Create<T>(string url) where T : class
{
ServicePointManager.Expect100Continue = false;
WebHttpBinding binding = new WebHttpBinding();
binding.MaxReceivedMessageSize = 1000000;
WebChannelFactory<T> factory =
new WebChannelFactory<T>(binding, new Uri(url));
T proxy = factory.CreateChannel();
return proxy;
}
public static T Create<T>(string url, string userName, string password)
where T : class
{
ServicePointManager.Expect100Continue = false;
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode =
WebHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
binding.UseDefaultWebProxy = false;
binding.MaxReceivedMessageSize = 1000000;
WebChannelFactory<T> factory =
new WebChannelFactory<T>(binding, new Uri(url));
ClientCredentials credentials = factory.Credentials;
credentials.UserName.UserName = userName;
credentials.UserName.Password = password;
T proxy = factory.CreateChannel();
return proxy;
}
}
So that I can use it as follows:
IMyRestService proxy = WebProxyFactory.Create<IMyRestService>(url, usr, pwd);
var result = proxy.GetSomthing(); // Fails right here
For this to work with Forms Authentication, I had to physically override the Authentication headers as follows:
var proxy = WebProxyFactory.Create<ITitleWorldService>(url, userName, password);
using (new OperationContextScope((IContextChannel)proxy))
{
var authorizationToken = GetBasicAuthorizationToken(userName, password);
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = authorizationToken;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
//var response = proxy.DoWork();
Console.WriteLine(proxy.SayHello());
}
Related
I am trying to consume a WSDL file from a third party in .net web API but it's retrieving.
Third-party sent me a Certificate that needs to be installed on the machine that wants to send a request and I already installed it.
In SoapUI it succeeded, with these configurations:
I can't mimic the configuration in SoupUI in .net.
This is what I have done:
var binding = GetBinding();
var endpointAddress = GetEndpointAddress("Endpoint URL");
if (endpointAddress != null)
{
ChannelFactory<IVitalEventsChannel> factory = null;
IVitalEventsChannel serviceProxy = null;
try
{
factory = new ChannelFactory<IVitalEventsChannel>(binding, endpointAddress);
factory.Credentials.UserName.UserName = "Username";
factory.Credentials.UserName.Password = "Passowrd";
serviceProxy = factory.CreateChannel();
gePersonalRequest gePersonalReq = new gePersonalRequest("National number");
serviceProxy.Open();
var remoteAddress = serviceProxy.RemoteAddress;
var state = serviceProxy.State;
var result = await serviceProxy.gePersonalAsync(gePersonalReq);
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (Exception ex)
{
//await client.CloseAsync();
factory.Close();
((ICommunicationObject)serviceProxy).Close();
return BadRequest(new { error = ex.Message });
}
}
Binding part looks like this:
private BasicHttpsBinding GetBinding()
{
var httpsBinding = new BasicHttpsBinding(BasicHttpsSecurityMode.TransportWithMessageCredential);
httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
//var httpsBinding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
WSHttpBinding b = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
b.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
httpsBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Basic;
httpsBinding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
httpsBinding.MaxBufferSize = int.MaxValue;
httpsBinding.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
httpsBinding.MaxReceivedMessageSize = int.MaxValue;
httpsBinding.AllowCookies = true;
return httpsBinding;
}
The request I sent gets an error this way. "Problems creating SAAJ object model"
Does anyone have an idea?
{
XYZEndpointClient client = new XYZEndpointClient();
XYZService.ServiceInput sorguServiceInput = new XYZService.sorguServiceInput();
string wso2Url = ConfigurationManager.AppSettings["url"];
Uri uri = new Uri(wso2Url);
AddressHeader addressHeader = AddressHeader.CreateAddressHeader("Content-Type", wso2Url,"text/xml;charset=utf-8");
client.Endpoint.Address = new System.ServiceModel.EndpointAddress(uri, addressHeader);
sorguServiceInput.ID = 1;
sorguServiceInput.Name = "Name";
var response= client.sorgula(sorguServiceInput);
}
This is the code I currently have
using (WebClient client = new WebClient()) {
WebProxy proxy = new WebProxy();
proxy.Address = new Uri(96.44.147.138:6060);
proxy.Credentials = new NetworkCredential(proxyUsername.Text, proxyPassword.Text);
proxy.UseDefaultCredentials = false;
proxy.BypassProxyOnLocal = false;
Console.WriteLine(client.DownloadString("http://bot.whatismyipaddress.com/"));
}
The proxy needs credentials.
I get an error on line proxy.Address = new Uri(96.44.147.138:6060);
saying
"The URI scheme is not valid."
Not sure what kind of value it's expecting
The Uri should consist of scheme host and optiona port. So you should use
proxy.Address = new Uri("http://96.44.147.138:6060");
Must be like;
using (var client = new WebClient())
{
var proxy = new WebProxy();
proxy.Address = new Uri("http://96.44.147.138:6060");
proxy.Credentials = new NetworkCredential(proxyUsername.Text, proxyPassword.Text);
proxy.UseDefaultCredentials = false;
proxy.BypassProxyOnLocal = false;
Console.WriteLine(client.DownloadString("http://bot.whatismyipaddress.com/"));
}
Example edit: Setting a global HTTP proxy in C# and .NET client classes
Is there anyway to integrate docushare with a windows store app?
I would like to login, get a file/folder list and have the possibility of downloading and uploading files.
Here is simple code snippet which can be good start to play with DocuShare. All possible request can be found in documentation.
Authentication + fetching properties for Collection-11 object
protected const string UsernameFormFieldName = "username";
protected const string PasswordFormFieldName = "password";
protected const string DomainFormFieldName = "domain";
const string CookieName = "AmberUser";
const string baseAdress = "http://host:port";
const string container = "/docushare";
static Uri CookieUrl = new Uri(new Uri(baseAdress), container);
const string root = "/xcm/v1/shadow/xcmAPI/root";
const string FolderInfoUri = "/xcm/v1/shadow/object/{0}/xcmAPI/properties";
const string ObjectVersion = "/xcm/v1/shadow/object/{0}/xcmAPI/version";
const string ObjectToTest = "Collection-11";
const string suffix = "?properties=title,mimetype";
static void Main(string[] args)
{
var token = Authenticate();
var requestUri = string.Format(container + FolderInfoUri, ObjectToTest) + suffix;
var response = GetResult(token, requestUri);
var content = response.Content.ReadAsStringAsync().Result;
}
private static string Authenticate()
{
const string AuthenticationPath = container + "/dsweb/ApplyLogin";
var form = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>(UsernameFormFieldName, "login"),
new KeyValuePair<string, string>(PasswordFormFieldName, "password"),
new KeyValuePair<string, string>(DomainFormFieldName, "domain"),
});
string authToken = null;
Execute((client, handler) =>
{
var task = client.PostAsync(AuthenticationPath, form, CancellationToken.None);
var response = task.Result;
var content = response.Content.ReadAsStringAsync().Result;
var cookie = handler.CookieContainer.GetCookies(CookieUrl);
authToken = cookie[CookieName].Value;
});
return authToken;
}
private static void Execute(Action<HttpClient, HttpClientHandler> request)
{
using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
handler.UseCookies = true;
handler.CookieContainer = new CookieContainer();
client.BaseAddress = new Uri(baseAdress);
request(client, handler);
}
}
private static HttpResponseMessage GetResult(string token, string uri)
{
HttpResponseMessage response = null;
Execute((client, handler) =>
{
handler.CookieContainer.Add(
CookieUrl,
new Cookie(CookieName, token));
var responseTask = client.GetAsync(uri);
response = responseTask.Result;
});
return response;
}
You should be able to do so with Docushare's HTML/XML API. For details on the Docushare API it looks like you'll need to register for the DocuShare Developer Network
Once you know what Docushare expects you should be able to connect to it from your Windows Store app with the HttpClient API. See Connecting to an HTTP server using Windows.Web.Http.HttpClient (XAML)
I am trying to write console application with the following scenario:
client first requests a token from an identity provider, and then uses this token to request a new token from a Resource STS
Using the following link: http://leastprivilege.com/2010/10/28/wif-adfs-2-and-wcfpart-6-chaining-multiple-token-services/
I managed get the token from Idp but didn't managed getting the token from Resource STS.
This is my code:
string RPRealm = "https://service.contoso.com/";
string RSTSRealm = "http://fsweb.contoso.com/adfs/services/trust";
string IdPstsEndpoint = "https://IdpAdfs.domain.com/adfs/services/trust/13/kerberosmixed";
string RSTSEndpoint = "https://fsweb.contoso.com/adfs/services/trust/13/IssuedTokenMixedSymmetricBasic256";
private static SecurityToken GetIdPToken(string rstsRealm, string IdPstsEndpoint)
{
using (var factory = new WSTrustChannelFactory(
new KerberosWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(new Uri(IdPstsEndpoint))))
{
WSTrustChannel channel = null;
factory.TrustVersion = TrustVersion.WSTrust13;
try
{
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress(rstsRealm),
KeyType = WSTrust13Constants.KeyTypes.Bearer,
};
channel = (WSTrustChannel)factory.CreateChannel();
RequestSecurityTokenResponse rstr;
SecurityToken token = channel.Issue(rst, out rstr);
return token;
}
finally
{
if (channel != null)
{
channel.Abort();
}
factory.Abort();
}
}
}
private static SecurityToken GetRSTSToken(SecurityToken IdPToken, string RSTSEndpoint, string RPRealm)
{
var binding = new WS2007FederationHttpBinding();
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Mode = WSFederationHttpSecurityMode.TransportWithMessageCredential;
using (var factory = new WSTrustChannelFactory(
binding,
new EndpointAddress(new Uri(RSTSEndpoint))))
{
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress(RPRealm),
KeyType = WSTrust13Constants.KeyTypes.Bearer,
};
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.SupportInteractive = false;
factory.ConfigureChannelFactory();
var channel = factory.CreateChannelWithIssuedToken(IdPToken);
RequestSecurityTokenResponse rstr;
SecurityToken token = channel.Issue(rst, out rstr);
return token;
}
}
I get this error:
The content type text/html of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8)
what is worng with my code?
Thanks in advance
ADFS does not support bearer tokens on its federation endoints. In other words, on your first hop you need to specify a KeyTypes.Symmetric on the RST.