如何使用使用自定义用户名验证和 PHP 页面的 WCF Web 服务?
Posted
技术标签:
【中文标题】如何使用使用自定义用户名验证和 PHP 页面的 WCF Web 服务?【英文标题】:How to consume a WCF Web Service that uses custom username validation with a PHP page? 【发布时间】:2011-10-02 21:26:06 【问题描述】:我很难从 php 站点使用安全的 WCF Web 服务。我对 PHP 的了解有限,我在网上找到了各种示例,但还没有成功。
我有一个 Silverlight 应用程序,它也使用这个 WebService,它工作正常。但是当我运行 PHP 站点时,我得到了这个错误:
MessageSecurityException:安全处理器无法在消息中找到安全标头。这可能是因为消息是不安全的错误,或者是因为通信双方之间存在绑定不匹配。如果服务配置了安全性并且客户端未使用安全性,则可能会发生这种情况。
我还尝试将 customBinding 更改为 basicHttpBinding。当我这样做时,不再调用自定义用户名验证器。但是,在我的 WCF 服务上使用 basicHttpBinding 并删除凭据验证“有效”(除了它不安全的事实之外)。所以问题似乎与安全消息有关。
谁能给我一个可以帮助我使这个 PHP 页面正常工作的工作示例或教程?
这是我的 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>
【问题讨论】:
【参考方案1】:我解决了这个问题。我不得不在 PHP 中扩展“SoapHeader”类以使其符合 WS-Security 标准。
解决办法如下:
PHP Header 类
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();
希望对其他人有所帮助!
感谢克里斯:Connecting to WS-Security protected Web Service with PHP
【讨论】:
是的,它帮助了我! 这对我也有帮助!很好的解决方案!【参考方案2】:SOAP 的身份验证有点有趣(或者可以),我使用了来自 http://www.php.net/manual/en/soapclient.soapclient.php#101503 的方法,请参阅来自 faebu 在 faebu dot ch 21-Dec-2010 02:58 的评论,因为这样做了几次.. . 它可能会有所帮助
基本上使用 CURL 来传递身份验证凭据...它可能/可能不适合您!
【讨论】:
我刚刚尝试过,但不幸的是,它不起作用。我看到正在创建 xml,但我仍然收到相同的异常。以上是关于如何使用使用自定义用户名验证和 PHP 页面的 WCF Web 服务?的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot Security 整合thymeleaf模板自定义登录页面,按需提示错误信息