I'm calling a third party webservice which uses credentials to validate the request. below is the code.
SmsWSIService smsService = new SmsWSIService();
smsService.Credentials = new NetworkCredential(smsUserName, smsPassword);
smsService.PreAuthenticate = true;
SendSMS.SendSMS objSendSmsReq = new SendSMS.SendSMS();
objSendSmsReq.From = smsFrmMobNo;
objSendSmsReq.Message = smsMsg
objSendSmsResp = smsService.SendSMS(objSendSmsReq);
but its giving me the error "401 Authorization Required". I'm sure that the credentials which i'm passing are correct. The webservice doesn't give any error when I check it with the SOAP UI 3.5.
Please help where I'm going wrong.
Have you installed Windows Authentication on IIS?
Related
I'm kind of new to the whole WCF and SOAP topic so please be kind.
I'm using a generated SOAP Client with .net6. In another project we successfully worked with the same Web Service using the old .net Framework 2.0 Web References and the same credentials.
Strange enough everything seemed to work fine at first. Until I realized, that it does not use the given credentials to authenticate. Instead it authenticates with my own domain user.
I also tried to get it to work with explicitly setting the binding with a BasicHttpBinding but I only could get the same broken logic to work or I got various authentication/protocol/security errors.
So it seems the authentication is basically working. It just doesn't use the provided credentials. So my question is: How can I configure it to work with the provided identity?
I also found out that it might have anything to do with a cached Windows token. But how can I get rid of it. How to prevent caching in the first place?
EDIT:
Specified the variable types explicitly.
string url = "http://someServer/AdministrationService.asmx";
AdministrationServiceSoapClient client = new AdministrationServiceSoapClient(
AdministrationServiceSoapClient.EndpointConfiguration.AdministrationServiceSoap,
url);
WindowsClientCredential credential = client.ClientCredentials.Windows;
credential.ClientCredential.UserName = "username";
credential.ClientCredential.Password = "password";
credential.ClientCredential.Domain = "DOMAIN";
GetServerInfoRequest getServerInfoRequest = new GetServerInfoRequest
{
// some stuff set here
};
GetServerInfoRequest getServerInfoReply = await client.GetServerInfoAsync(getServerInfoRequest);
As far as I know, BasicHttpBinding has security disabled by default, but can be added setting the BasicHttpSecurityMode to a value other than None in the constructor. It can be configured according to the instructions in BasicHttpBinding and BasicHttpBinding Constructors.
By default, setting up client credentials involves two steps: determining the type of client credential required by the service and specifying an actual client credential, as described in this document.
After waiting a day it is working. It seems that the cached credentials became invalid somehow.
Strange enough the simple service creation from above is not working anymore. Instead I have to use the following.
var client = new AdministrationServiceSoapClient(
new BasicHttpBinding()
{
Security = new BasicHttpSecurity()
{
Mode = BasicHttpSecurityMode.TransportCredentialOnly,
Message = new BasicHttpMessageSecurity()
{
ClientCredentialType = BasicHttpMessageCredentialType.UserName,
},
Transport = new HttpTransportSecurity()
{
ClientCredentialType = HttpClientCredentialType.Windows,
ProxyCredentialType = HttpProxyCredentialType.Windows,
}
},
},
new EndpointAddress(url));
I am attempting to perform some basic integration using Acumatica's web services. Unfortunatly, I'm having problems logging in. According to their documentation, this process should look something like:
apitest.Screen context = new apitest.Screen();
context.CookieContainer = new System.Net.CookieContainer();
context.AllowAutoRedirect = true;
context.EnableDecompression = true;
context.Timeout = 1000000;
context.Url = "http://localhost/WebAPIVirtual/Soap/APITEST.asmx";
LoginResult result = context.Login("admin", "E618");
Simple enough. However, after creating and importing a WSDL file from Acumatica into Visual Studio, I found I don't have a Screen object. I do, however have a ScreenSoapClient object, which has a similar Login() method.
ScreenSoapClient context = new Acumatica.ScreenSoapClient("ScreenSoap");
LoginResult result = context.Login("username", "password");
That part works. In fact, the LoginResult give me a session ID. However, if I try to make any calls to the service, such as:
CR401000Content cr401000 = context.CR401000GetSchema();
I get an error: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> PX.Data.PXNotLoggedInException: Error #185: You are not currently logged in.
While the version of Acumatica we're using does appear to be slightly newer, I'm unsure why the Screen() object isn't available. Consequently, if I try a bad username/password, Login() does fail (as it should). From what I can the tell, the ScreenSoapClient class is using service model details from web.config, so it's getting the endpoint address and other details there.
Is there something I'm missing or doing wrong?
As i see, you use WCF to create your service reference.
So you should enable cookies in service binding:
var binding = new BasicHttpBinding()
{
AllowCookies = true
};
var address = new EndpointAddress("http://localhost/WebAPIVirtual/Soap/APITEST.asmx");
var c = new ServiceReference1.ScreenSoapClient(binding, address);
Or, you can use old asmx web service reference (http://msdn.microsoft.com/en-us/library/bb628649.aspx).
Then everything will be same as in Acumatica`s documentation.
As noted in a comment above, I was able to make contact with a representative from Acumatica. He had me remove then recreate the service references in our project and try again. That apparently did the trick and the "Error #185: You are not currently logged in" error went away.
When I was trying to post messages to Twitter, the above error coming. How to get rid of that error?
The stacktrace is the following:
Exception = {"The remote server returned an error: (407) Proxy Authentication Required."} ExceptionStatus = ProtocolError
Code:
private string GetOAuthUrl()
{
IFluentTwitter twitter;
//Override the callback url if one was entered
if (CallbackUrl != null && CallbackUrl.Trim().Length > 0)
{
twitter = FluentTwitter.CreateRequest().Configuration.UseHttps().Authentication.GetRequestToken(ConsumerKey, ConsumerSecret, CallbackUrl);
}
else
{
twitter = FluentTwitter.CreateRequest().Configuration.UseHttps().Authentication.GetRequestToken(ConsumerKey, ConsumerSecret);
}
var response = twitter.Request();
UnauthorizedToken UnauthorizedToken = response.AsToken();
string AuthorizationUrl = FluentTwitter.CreateRequest().Authentication.GetAuthorizationUrl(UnauthorizedToken.Token);
return AuthorizationUrl;
}
If fluent twitter is using WebRequests under the covers, then you need to specify credentials for the proxy using code like this:
System.Net.WebRequest.DefaultWebProxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
This will tell all web requests to use the credentials of the user running the application to authenticate with the proxy.
To make this work, you will need to configure the application to run under a service account which has been granted access to the proxy server. You can then tie down this service account so that it has as few permissions as possible to run the service.
If your application needs to run under an account which doesn't have rights to use the proxy server, you can specify the credentials explicitly as follows:
System.Net.NetworkCredential credentials = new System.Net.NetworkCredential("username", "password", "domain");
System.Net.WebRequest.DefaultProxy.Credentials = credentials;
The down side to this is that you have to store those credentials somewhere, and that they could be captured by an attacker if they managed to compromise your application. In some environments, this is not acceptable from a security standpoint.
I use .Net, and Visual Studio 2010.
I downloaded the WSDLs and corrected the maxOccurs error, and adding the WSDL as a Web Reference works just fine.
The problem occurs when I call SetExpressCheckout. The error simply says, Version is not supported. I have checked the version of the WSDL, which is 76.0 - and should be correct AFAIK.
The Web Service endpoint being used is this: https://api.sandbox.paypal.com/2.0/
Is there anywhere I need to specify the version, or is the service endpoint being used wrong?
If anyone has the same problem, you need to specify the version:
PayPalAPIAASoapBinding api = new PayPalAPIAASoapBinding();
// Service Provider's API Credentials
api.RequesterCredentials = new CustomSecurityHeaderType();
api.RequesterCredentials.Credentials = new UserIdPasswordType();
api.RequesterCredentials.Credentials.Username = this.Username;
api.RequesterCredentials.Credentials.Password = this.Password;
api.RequesterCredentials.Credentials.Signature = this.ApiSignature;
// The merchant's PayPal e-mail address (3rd party authentication)
api.RequesterCredentials.Credentials.Subject = this.CustomerId;
SetExpressCheckoutReq req = new SetExpressCheckoutReq();
req.SetExpressCheckoutRequest = new SetExpressCheckoutRequestType();
req.SetExpressCheckoutRequest.SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType();
req.SetExpressCheckoutRequest.Version = "74.0";
Right now the Sandbox runs in v 74.0, and production in 76.0. PayPal doesn't always run same versions across their environments.
I am able to access the web service from the web browser but on the same computer if I try to connect to the web service through code I get a The remote server returned an error: (407) Proxy Authentication Required. error.
I have supplied all the credentials required. Here is my code -
MyWebService objWS = new MyWebService(); // my Web service object
// My credentials
System.Net.NetworkCredential cr = new System.Net.NetworkCredential(MyDomainUserName, UserPassword, DomainController);
System.Net.WebProxy pr = new System.Net.WebProxy(ProxyServer, ProxyPort);
pr.Credentials = cr; //Using my credentials for the local proxy
// Web Service credentials
System.Net.NetworkCredential cr1 = new System.Net.NetworkCredential("My_WebService_UserName", "My_WebService_Pwd");
objWS.Credentials = cr1; // Using WebService credentials to the WS object
//objWS.Credentials = CredentialCache.DefaultCredentials; // I even tried Using default credentials but this didn't help.
objWS.Proxy = pr;
Object result = objWS.WebMethod1(param1,param2,param3);
But, this throws an error - The remote server returned an error: (407) Proxy Authentication Required.
Any idea, what am I doing wrong here? Thanks.
You need to update your config file like this to fix this problem.
<system.net>
<defaultProxy useDefaultCredentials="true"> </defaultProxy>
</system.net>
It isn't clear in this blog post, but this isn't either/or. Both things are required to fix your problem.
http://blogs.msdn.com/b/jpsanders/archive/2009/03/24/httpwebrequest-webexcepton-the-remote-server-returned-an-error-407-proxy-authentication-required.aspx
You get this error because you are trying to access the service from behind a proxy.
Try to use this code (you probably only need the last line):
//Set the system proxy with valid server address or IP and port, for example.
System.Net.WebProxy pry = new System.Net.WebProxy("172.16.0.1",8080);
//The DefaultCredentials should be enough.
pry.Credentials = CredentialCache.DefaultCredentials;
GlobalProxySelection.Select = pry;
This means that your proxy needs some credentials(user name and pasword.) Figure out what they are and set them on pry.