如何将用户名/密码凭据从 php 客户端传递到自托管 wcf 服务?

发布于 2024-11-08 07:37:54 字数 4110 浏览 4 评论 0原文

我有一个自托管 wcf 服务,只需添加 2 个数字并返回值。它工作正常,但我不确定如何通过 php 客户端发送用户名和密码,因此它将根据我的 CustomUserNamePasswordValidator 进行验证。这是添加方法的实现:

public class MathService : IMathService
{
    public double Add(double x, double y)
    {
        return x + y;
    } 
}

这是我当前的 App.Config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
  <service behaviorConfiguration="MyServiceBehavior" name="WcfWithPhp.MathService">
    <endpoint address="" binding="basicHttpBinding" contract="WcfWithPhp.IMathService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8731/MathService" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

我正在像这样启动服务:

static void Main(string[] args)
{
    ServiceHost host = new ServiceHost(typeof(WcfWithPhp.MathService));
    host.Open();

    Console.WriteLine("Math Service Host");
    Console.WriteLine("Service Started!");

    foreach (Uri address in host.BaseAddresses)
    {
        Console.WriteLine("Listening on " + address);
    }

    Console.WriteLine("Press any key to close the host...");
    Console.ReadLine();
    host.Close();
}

对于 php 客户端,我正在做:

<?php

header('Content-Type: text/plain');

echo "WCF Test\r\n\r\n";

// Create a new soap client based on the service's metadata (WSDL)
$client = new SoapClient("http://localhost:8731/MathService?wsdl");

$obj->x = 2.5;
$obj->y = 3.5;

$retval = $client->Add($obj);

echo "2.5 + 3.5 = " . $retval->AddResult;

?>

上面的内容无需身份验证即可正常工作,但我希望能够对来自 phpclient 的用户名和密码。当他们尝试访问我的服务时,我希望通过 UserNamePasswordValidator 的重写 Validate 方法来验证用户名和密码,该方法当前定义为:

public override void Validate(string userName, string password)
{
        if (string.IsNullOrEmpty(userName))
            throw new ArgumentNullException("userName");
        if (string.IsNullOrEmpty(password))
            throw new ArgumentNullException("password");

        // check if the user is not test
        if (userName != "test" || password != "test")
            throw new FaultException("Username and Password Failed");
 }

我只是使用 test 和 test 作为用户名和密码的示例。我知道我必须设置修改行为配置并进行绑定配置,因此该服务将使用 CustomUserNamePasswordValidator,但由于我不了解 PHP,所以我不确定如何将凭据从 php 发送到 wcf 服务并且发送凭据后,我不知道如何在 wcf 服务中设置它。我没有创建 wcf 服务。我以为我可以做 client.ClientCredentials.UserName.UserNameclient.ClientCredentials.UserName.Password,但这只是当我创建 .NET 客户端时,我不是。

我的另一个问题是,如果客户端是 php 客户端,我是否只能使用 basicHttpBinding?

另外,理想情况下我想做的是将肥皂请求从 php 客户端发送到 wcf 服务,因此如果有人能为我指出正确的方向,那就太好了。

我刚刚尝试了以下操作,但它不起作用(调用了 Add,但未经过身份验证)

$sh_param = array('userName' => 'test', 'passWord' => 'test2');

$headers = new SoapHeader('http://localhost:8731/MathService.svc','UserCredentials',   
$sh_param,false);

$client->__setSoapHeaders(array($headers));

更新: 我的 PHP Soap 客户端初始化现在是:

$client = new SoapClient('http://localhost:8731/MathService?wsdl',
                         array('login' => "test2", 
                               'password' => "test",
                               'trace'=>1));

通过执行上述操作,它在请求中添加了以下内容:

`Authorization: Basic dGVzdDI6dGVzdA==`

但是,我的 wcf 服务托管在控制台应用程序中,没有获取此授权,我有一个自定义用户名验证器,它有一个用户名的 test 和密码的 test 的硬编码值,但是当我尝试“test2”登录时,它仍在调用该方法。我正在使用 TransportWithCredentialOnly 和 Message="UserName"

I have a self-hosted wcf service that just adds 2 numbers and returns the value. It works fine, but I am not sure how I can send the username and password through the php client, so it will validate against my CustomUserNamePasswordValidator. Here is the implementation for the Add Method:

public class MathService : IMathService
{
    public double Add(double x, double y)
    {
        return x + y;
    } 
}

Here is my current App.Config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
  <service behaviorConfiguration="MyServiceBehavior" name="WcfWithPhp.MathService">
    <endpoint address="" binding="basicHttpBinding" contract="WcfWithPhp.IMathService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8731/MathService" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

I am starting the service like this:

static void Main(string[] args)
{
    ServiceHost host = new ServiceHost(typeof(WcfWithPhp.MathService));
    host.Open();

    Console.WriteLine("Math Service Host");
    Console.WriteLine("Service Started!");

    foreach (Uri address in host.BaseAddresses)
    {
        Console.WriteLine("Listening on " + address);
    }

    Console.WriteLine("Press any key to close the host...");
    Console.ReadLine();
    host.Close();
}

For the php client, I am doing:

<?php

header('Content-Type: text/plain');

echo "WCF Test\r\n\r\n";

// Create a new soap client based on the service's metadata (WSDL)
$client = new SoapClient("http://localhost:8731/MathService?wsdl");

$obj->x = 2.5;
$obj->y = 3.5;

$retval = $client->Add($obj);

echo "2.5 + 3.5 = " . $retval->AddResult;

?>

The above works fine without authentication, but I want to be able to authenticate the username and password from the phpclient. When they try to access my service, I want the username and password to validate through the overriden Validate method of the UserNamePasswordValidator, which is currently defined as:

public override void Validate(string userName, string password)
{
        if (string.IsNullOrEmpty(userName))
            throw new ArgumentNullException("userName");
        if (string.IsNullOrEmpty(password))
            throw new ArgumentNullException("password");

        // check if the user is not test
        if (userName != "test" || password != "test")
            throw new FaultException("Username and Password Failed");
 }

I am just using test and test as an example for the username and password. I know I have to set the modify the behavior configuration and do a binding configuration, so the service will use the CustomUserNamePasswordValidator, but since I don't know PHP, I am not sure how to send the credentials from php to the wcf service and once the credentials are sent, I don't know how to set it in the wcf service. I am not creating a wcf service. I thought I could do client.ClientCredentials.UserName.UserName and client.ClientCredentials.UserName.Password, but this is only if I am creating .NET client which I am not.

Another question I had was that if the client is a php client, am I restricted to only basicHttpBinding?

Also, ideally what I would like to do is send a soap request from the php client to the wcf service, so if anyone can point me in the right direction for this, it would be great.

I just tried the following, but it didn't work (Add was called, but it wasn't authenticated)

$sh_param = array('userName' => 'test', 'passWord' => 'test2');

$headers = new SoapHeader('http://localhost:8731/MathService.svc','UserCredentials',   
$sh_param,false);

$client->__setSoapHeaders(array($headers));

UPDATE:
My PHP Soap Client initialization is now:

$client = new SoapClient('http://localhost:8731/MathService?wsdl',
                         array('login' => "test2", 
                               'password' => "test",
                               'trace'=>1));

By doing the above, it added the following in the Request:

`Authorization: Basic dGVzdDI6dGVzdA==`

However, my wcf service which is hosted in a console app, is not picking up this authorization, I have a custom username validator which has a hard-coded value of test for the username and test for the password, but when I try "test2" for the login, it is still calling the method. I am using TransportWithCredentialOnly and Message="UserName"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧街凉风 2024-11-15 07:37:54

尝试 SoapClient 构造函数重载:

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

这是文档:http://www.php。 net/manual/pl/soapclient.soapclient.php

Try SoapClient constructor overload:

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

And here is the doc: http://www.php.net/manual/pl/soapclient.soapclient.php

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文