如何使用将自定义用户名验证与PHP页面一起使用的WCF Web服务? [英] How to consume a WCF Web Service that uses custom username validation with a PHP page?

查看:61
本文介绍了如何使用将自定义用户名验证与PHP页面一起使用的WCF Web服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难从PHP站点使用安全的WCF Web服务.我对PHP的了解有限,我在网络上找到了许多示例,但尚未成功使它们工作.

I'm having hard time consuming a secure WCF Web Service from a PHP site. My knowledge in PHP are limited, I found various examples on the Web but didn't succeeded making them working yet.

我有一个Silverlight应用程序,该应用程序也使用了此WebService,并且运行良好.但是当我运行PHP网站时,出现此错误:

I have a Silverlight application that also consume this WebService and it works fine. But when I run the PHP site, I get this error :

MessageSecurityException:安全处理器无法在消息中找到安全标头.这可能是因为消息是不安全的故障,或者是由于通信双方之间存在绑定不匹配.如果将服务配置为具有安全性,并且客户端未使用安全性,则会发生这种情况.

MessageSecurityException: Security processor was unable to find a security header in the message. This might be because the message is an unsecured fault or because there is a binding mismatch between the communicating parties. This can occur if the service is configured for security and the client is not using security.

我还尝试将customBinding更改为basicHttpBinding.当我这样做时,不再调用自定义用户名验证器.但是,使用basicHttpBinding并删除我的WCF服务上的凭据验证有效"(除了它不安全之外).因此,问题似乎与安全消息有关.

I also tried to change the customBinding to a basicHttpBinding. When I do that, the Custom Username validator is not called anymore. But, using basicHttpBinding and removing credentials validation on my WCF Service "works" (Besides the fact that it is unsecured). So the problem seems to related to the security message.

有人可以给我一个可行的示例或教程来帮助我使此PHP页面正常工作吗?

Could someone give me a working example or tutorial that could help me making this PHP page works?

这是我的PHP代码:

    $options = array( 
            'soap_version'  => SOAP_1_1, 
            'exceptions'    => true, 
            'trace'         => 1, 
            'cache_wsdl'    => WSDL_CACHE_NONE,
            'Username'      => 'MyUserName', 
            'password'      => 'MyPassword');

$client = new SoapClient('https://UrlToService/Service.svc?wsdl', $options); 

try
{
    $phpresponse = $client->Get(); 

    print $phpresponse->GetResult->Version;
    echo "</b><BR/><BR/>";
}
catch(Exception $e) 
{ 
    echo "<h2>Exception Error!</h2></b>"; 
    echo $e->getMessage(); 
    echo "<BR/><BR/>";
}

WCF配置

<behavior name="sslBehavior">
   <serviceMetadata httpsGetEnabled="true" />
   <serviceDebug includeExceptionDetailInFaults="true" />
   <serviceCredentials>
      <userNameAuthentication userNamePasswordValidationMode="Custom"   customUserNamePasswordValidatorType="MyNamespace.ServiceUserNameValidator, MyNamespace" />
   </serviceCredentials>
   <serviceSecurityAudit
    auditLogLocation="Application"
    serviceAuthorizationAuditLevel="Failure"
    messageAuthenticationAuditLevel="Failure"
    suppressAuditFailure="true" />
</behavior>

<customBinding>
    <binding name="sslCustomBinding">
      <security authenticationMode="UserNameOverTransport" includeTimestamp="true" allowInsecureTransport="true">
        <localServiceSettings maxClockSkew="00:10:00" />
        <localClientSettings maxClockSkew="00:10:00" />
        <secureConversationBootstrap />
      </security>
      <textMessageEncoding messageVersion="Soap11" />
      <httpsTransport />
    </binding>
  </customBinding>

<service behaviorConfiguration="sslBehavior" name="MyNamespace.Services.Service">
    <endpoint address="" binding="customBinding" 
              bindingConfiguration="sslCustomBinding" contract="MyNamespace.ServiceContracts.IService" />
    <host>
      <baseAddresses>
        <add baseAddress="https://UrlToService/Services/" />
      </baseAddresses>
    </host>
  </service>

推荐答案

我解决了这个问题.我必须在PHP中扩展"SoapHeader"类,以使其符合WS-Security标准.

I solved the problem. I had to extends the "SoapHeader" class in PHP to make it compliant with the WS-Security standard.

这是解决方法:

PHP标头类

class WsseAuthHeader extends SoapHeader 
{
    private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
    function __construct($user, $pass, $ns = null) 
    {    
        if ($ns) 
        {        
            $this->wss_ns = $ns;    
        }    

        $auth = new stdClass();    

        $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);     
        $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);    
        $username_token = new stdClass();    
        $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);     
        $security_sv = new SoapVar(        
                                new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),        
                                SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);    

        parent::__construct($this->wss_ns, 'Security', $security_sv, true);
    }
}

PHP客户端调用

$options = array( 
            'soap_version'    => SOAP_1_1, 
            'exceptions'      => true, 
            'trace'           => 1, 
            'wdsl_local_copy' => true
            );


$username = "MyUser";
$password = "MyPassword";

$wsse_header = new WsseAuthHeader($username, $password);    

$client = new SoapClient('https://UrlToService/Service.svc?wsdl', $options); 
$client->__setSoapHeaders(array($wsse_header));

try
{
    $phpresponse = $client->Get(); 

    print $phpresponse->GetResult->Version;
    echo "</b><BR/><BR/>";
}
catch(Exception $e) 
{ 
    echo "<h2>Exception Error!</h2></b>"; 
    echo $e->getMessage(); 
}

希望它会对其他人有所帮助!

Hope it will helps someone else!

感谢Chris:连接到受WS-Security保护的Web用PHP服务

这篇关于如何使用将自定义用户名验证与PHP页面一起使用的WCF Web服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆