使用C#在php Web服务中进行基本身份验证

时间:2013-12-10 12:52:02

标签: c# authentication soap webservice-client

我试图使用c#中的代码对webservice php进行身份验证:

// 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。 并使用此代码:

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

我收到此错误:身份验证失败。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

在项目中添加服务引用,您唯一需要做的就是这样:

    var client = new ServiceReference1.servercraPortTypeClient();
    client.ClientCredentials.UserName.UserName = "name";
    client.ClientCredentials.UserName.Password = "password";

    client.Homologadas("2");

    client.Close();

注意:绑定应该是basicHttpBinding。

生成的配置:

<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>

答案 1 :(得分:0)

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

使用身份验证时,http请求在与服务器的初始通信期间不会包含身份验证。它希望服务器生成401错误,此时它将发送身份验证。

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

解决方案

重写GetWebRequest方法并将身份验证标头插入HTTP标头。命名空间和类必须与您尝试为其生成标头的命名空间和类相匹配。

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