问题
I'm trying to authenticate to a webservice php with this code in c#:
// Create the binding.
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.None;
myBinding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
myBinding.Name = "Remessa";
myBinding.Namespace = "cramg.cra21.com.br";
myBinding.AllowCookies = true;
EndpointAddress ea = new
EndpointAddress("http://cramg.cra21.com.br/cramg/xml/protestos.php");
CRAMG.servercraPortTypeClient t =
new CRAMG.servercraPortTypeClient(myBinding, ea);
t.ClientCredentials.UserName.UserName = "cromg";
t.ClientCredentials.UserName.Password = "
t.Open();
t.Remessa("tfasd", "fasfa");
I get error 500. And with this code:
br.com.cra21.cramg.servercra a = new br.com.cra21.cramg.servercra();
System.Net.CredentialCache myCredentials = new System.Net.CredentialCache();
a.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)";
NetworkCredential netCred = new NetworkCredential("cromg", "1234");
myCredentials.Add(new Uri(a.Url), "Basic", netCred);
a.Credentials = myCredentials;
a.UseDefaultCredentials = false;
string retorno = a.Homologadas("2");
I get this error: Authentication failed. Can anyone help?
回答1:
Add a Service Reference into your project and the the only thing you have to do is something like this:
var client = new ServiceReference1.servercraPortTypeClient();
client.ClientCredentials.UserName.UserName = "name";
client.ClientCredentials.UserName.Password = "password";
client.Homologadas("2");
client.Close();
Note: the binding should be basicHttpBinding.
Generated configuration:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="server.craBinding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://cramg.cra21.com.br/cramg/xml/protestos.php"
binding="basicHttpBinding" bindingConfiguration="server.craBinding"
contract="ServiceReference1.servercraPortType" name="server.craPort" />
</client>
</system.serviceModel>
</configuration>
回答2:
I Found the solution here: http://social.msdn.microsoft.com/Forums/en-US/51ee408b-2b77-49e2-8066-308e1ca48240/problems-with-basic-http-authentication-over-soap-webservice
when using authentication, the http request will not contain authentication during the initial communication with the server. It expects the server to generate a 401 error, at which point it will send the authentication.
So what happens is the server does not need the authentication, only the webservice running on it. The webservice will not return a 401 error instead it returns an error that the API cannot be accessed via an anonymous user. Even using preauthenticate will not fix the issue, or using credentials cache.
The Solution
Override the GetWebRequest method and insert an authentication header into the HTTP header. The namespace and class must match the namespace and class that you are attempting to generate the headers for.
in c#:
public class serverBasicAuthentication : br.com.cra21.cramg.servercra
{
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest) base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkcredential = base.Credentials.GetCredential(uri,"Basic");
if (networkcredential != null)
{
Byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkcredential.UserName + ":" + networkcredential.Password);
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
}
else
throw new ApplicationException("No network credentials") ;
}
return request;
}
}
来源:https://stackoverflow.com/questions/20495105/basic-authentication-in-php-webservice-with-c