2011-07-05 63 views
0

我有一个关于用PHP编写的web服务的问题。在.NET客户端上使用PHP webservice的问题

要实例SoapClient使用PHP,我通过以下参数对SoapClient方法在PHP这样的:

$client = new SoapClient("some.wsdl", 
         array('login' => "some_name", 
           'password' => "some_password" 
         )); 

要调用与PHP web服务方法,能正常工作。但是我的同事在使用.NET发送证书时遇到了问题。

有谁知道这是如何通过.NET?

更新,净客户端配置

<basicHttpBinding> 
    <binding name="webserviceControllerBinding"> 
     <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Basic"/> 
     </security> 
    </binding> 
</basicHttpBinding> 

而在代码:

client.ClientCredentials.UserName.UserName = "username"; 
client.ClientCredentials.UserName.Password = "password"; 

更新2:

建立所述客户端(在PHP)

$client = new 
SoapClient("http://***.***.***/********/httpdocs/webservice/wsdl?wsdl", 
    array(
     'uri'  => "http://***.***.***/***/httpdocs/webservice/webservice", 
     'login' => "*****", 
     'password' => "*****" 
)); 

处理请求并引用该类的服务器。

public function webservice() 
    parent::__construct(); 
    ini_set('soap.wsdl_cache_enabled', 0); 
    $this->presenter  = "NONE"; 
    $server    = new SoapServer("http://***.***.***/***/httpdocs/webservice/wsdl?wsdl", array('uri' => "http://***.***.***/")); 

    $server->setClass( "Model_Webservice"); 
    $server->handle(); 

而webservice类中的这一块处理用户名和密码认证。

class Model_Webservice extends Object_Database 
{ 

public function __construct() 
{ 
    parent::__construct(); 

    $accesslog  = Log::factory('file', $this->config->log->access , 'ACCESS LOG'); 

    if(!isset($_SERVER['PHP_AUTH_USER']) || trim($_SERVER['PHP_AUTH_USER']) == "") 
    { 
    $accesslog->log("[denied] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] no username supplied"); 
    throw new SOAPFault("Authentication failed - reason: no username supplied", 401); 
    } 
    elseif(!isset($_SERVER['PHP_AUTH_PW']) || trim($_SERVER['PHP_AUTH_PW']) == "") 
    { 
    $accesslog->log("[denied] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] no password supplied"); 
    throw new SOAPFault("Authentication failed - reason: no password supplied", 401); 
    } 
    else 
    { 
    $user = new User(null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); 

    if($user->getId() > 0) 
    { 
     $accesslog->log("[approved] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] User logged in"); 
    } 
    if(!$user->getId() > 0) 
    { 
     $accesslog->log("[denied] [soapclient " . $_SERVER['REMOTE_ADDR'] . "] incorrect username and password combination"); 
     throw new SOAPFault("Authentication failed - reason: incorrect username and password combination", 401); 
    } 
    } 
} 

更新3

我基于调整后的配置收到以下错误消息

<bindings> 
     <basicHttpBinding> 
      <binding name="webserviceControllerBinding"> 
       <security mode="Message">     
        <message clientCredentialType="UserName" algorithmSuite="Default" /> 
       </security> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 

BasicHttp结合要求BasicHttpBinding.Security.Message.ClientCredentialType相当于用于安全消息的BasicHttpMessageCredentialType.Certificate凭证类型。 为UserName凭证选择Transport或TransportWithMessageCredential安全性。'

我不想使用证书或https。

+0

他们如何指定的凭据和你使用的身份验证机制? – jgauffin

+0

我必须说,如果我关闭PHP服务器的安全性,我们可以使用.NET调用Web服务。但是,这是其他程序员使用: <绑定名称= “webserviceControllerBinding”> <安全模式= “TransportCredentialOnly”> <传输clientCredentialType = “基本”/> client.ClientCredentials .UserName.UserName =“username”; client.ClientCredentials.UserName.Password =“password”; –

+0

总是添加代码作为您问题的更新。否则将不可能遵循它。 – jgauffin

回答

1

我建议使用类似Fiddler这样的工具来捕获正在运行的PHP客户端和您的非功能.NET客户端发送的实际SOAP XML数据。

如果您比较两个请求,您很有可能会看到其中的差异,并能够解决问题。

希望有所帮助。

+0

我已经安装了Fiddler,但我似乎无法赶上请求发送到服务器。只有反应正在显示。 –

+0

很奇怪。如果你能看到回应,我原以为你应该能够看到请求。 – Spudley

1

我敢打赌,.NET中的WCF不会发送身份验证头(默认情况下),除非从Web服务获取一个质询。

如果未提供用户名或密码,则应返回HTTP状态码401,如果用户名/密码不正确,则应返回http状态码403。

换句话说:删除SoapException并返回正确的HTTP状态码。

更新为响应更新3

嘛。这个异常与它是一个PHP web服务无关。这是一个完全不同的问题。由于在没有证书的情况下使用BASIC身份验证会在CLEAR TEXT中发送密码,因此会引发错误。

我会切换到像DIGEST身份验证更安全的东西。

+0

说实话,它返回SOAPFault:身份验证失败 - 原因:没有提供用户名。这意味着它没有通过第一个用户名/密码检查。所以.NET甚至没有向web服务发送任何东西。 –

+0

他们在.NET中遇到了什么样的异常呢?你必须提供所有相关信息 – jgauffin

0
MessageHeader header= MessageHeader.CreateHeader("My-CustomHeader","http://myurl","Custom Header."); 

     using (phptoebiTestclient.ServiceReference1.webserviceControllerPortTypeClient client = new phptoebiTestclient.ServiceReference1.webserviceControllerPortTypeClient()) 
     { 
      using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) 
      { 
       OperationContext.Current.OutgoingMessageHeaders.Add(header); 
       HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty(); 
       byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("username:password");      
       httpRequestProperty.Headers.Add("Authorization: Basic "+ System.Convert.ToBase64String(toEncodeAsBytes));            
       OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty; 
       string str = client.getVacanciesReference(""); 
      }         
     } 

以上代码已经解决了我的问题(我用这些网址,供参考)

http://caught-in-a-web.blogspot.com/2008/04/how-to-add-custom-http-header-in-wcf.html http://en.wikipedia.org/wiki/Basic_access_authentication

相关问题