在PHP Web服务的基本身份验证使用C#

问题描述:

我想验证与此code在C#中的Web服务PHP的:

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");

我得到错误500。
而与此code:

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?

我在这里找到了解决办法:
http://social.msdn.microsoft.com/Forums/en-US/51ee408b-2b77-49e2-8066-308e1ca48240/problems-with-basic-http-authentication-over-soap-webservice

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

使用认证时,http请求将不与服务器的初始通信期间包含认证。该公司预计服务器生成一个401错误,在这一点上,它会发送身份验证。

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.

那么会发生什么是服务器不需要身份验证,只有在其上运行web服务。该Web服务将不会返回401错误,而不是返回该API无法通过一个匿名用户访问一个错误。即使使用preauthenticate不会解决问题,或使用凭证高速缓存。

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.

解决方案

重写GetWebRequest方法和插入认证头插入到HTTP头。命名空间和类必须在命名空间和类,您正试图生成标题匹配。

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.

在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; 
        }
    }