繁体   English   中英

安全的wcf(使用使用者名称密码验证器)无法从php用户端运作

[英]Secure wcf (using username password validator) not working from php client

我已经在.Net C#(框架4.5)中使用wsHttpBinding构建了一个简单的安全wcf,并从.Net C#(也)客户端使用了它,并且一切正常。 但是,当我尝试通过从wcs服务调用方法从php(5.5)客户端使用It时,该客户端无法正常工作,它进入了无限循环并且没有显示任何错误消息 ,只是循环而已

一种。 以下是我的wcf ServiceContractOperationContract

namespace CenteralServices
{
    [ServiceContract]
    public interface IAdminServices
    {
        [OperationContract]
        int Add(int x, int y);
    }
}


b。 以下是wcf的配置文件Web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <services>
            <service name= "CentralTicketServicesSystem.AdminSystem" 
                behaviorConfiguration="customBehaviour">
                <endpoint address="AdminServices" 
                        binding="wsHttpBinding" 
              contract="CentralTicketServicesSystem.IAdminServices"
              bindingConfiguration="ServiceBinding"
              behaviorConfiguration="MyEndPointBehavior">
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8080/AdminServicesSystem" />
      </baseAddresses>
    </host>
  </service>
</services>

<bindings>
  <wsHttpBinding>
    <binding name="ServiceBinding"
             openTimeout="00:10:00"
             closeTimeout="00:10:00"
             receiveTimeout="00:10:00"
             sendTimeout="00:10:00">
      <security mode="Message" >
        <message clientCredentialType="UserName"/>
      </security>

    </binding>
  </wsHttpBinding>
</bindings>

<behaviors>
  <endpointBehaviors>
    <behavior name="MyEndPointBehavior">
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="customBehaviour">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
      <serviceAuthorization principalPermissionMode="Custom">
        <authorizationPolicies>
          <add policyType="CentralServicesHost.AuthorizationPolicy, CentralServicesHost" />
        </authorizationPolicies>
      </serviceAuthorization>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom"
           customUserNamePasswordValidatorType="CentralServicesHost.UserAuthentication, CentralServicesHost"/>
        <serviceCertificate findValue="15 63 10 5e b6 4b 4d 85 4b 2e 4d 5b ec 85 02 ec"
                            storeLocation="LocalMachine"
                            x509FindType="FindBySerialNumber"
                            storeName="My"/>
      </serviceCredentials>
    </behavior>
    <behavior name="mexBehaviour" >
      <serviceMetadata httpGetEnabled="true" />
    </behavior>

            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>



C。 以下是UserAuthentication类:

namespace CentralServicesHost
{
    public class UserAuthentication : UserNamePasswordValidator
    {

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

            if (userName != "test" && password != "test")
                 throw new FaultException("Unknown Username or Incorrect Password.");
        }
    }
}



d。 以下是AuthorizationPolicy类:

namespace CentralServicesHost
{
    public class AuthorizationPolicy : IAuthorizationPolicy
    {
        Guid _id = Guid.NewGuid();
        // this method gets called after the authentication stage
        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        {
            // get the authenticated client identity
            IIdentity client = GetClientIdentity(evaluationContext);
            // set the custom principal
            evaluationContext.Properties["Principal"] = new CustomPrincipal(client);
            return true;
        }
        private IIdentity GetClientIdentity(EvaluationContext ec)
        {
            object obj;
            if (!ec.Properties.TryGetValue("Identities", out obj))
                throw new Exception("No Identity found");
            IList<IIdentity> identities = obj as IList<IIdentity>;
            if (identities == null || identities.Count <= 0)
                throw new Exception("No Identity found");
            return identities[0];
        }

        public System.IdentityModel.Claims.ClaimSet Issuer
        {
            get { return ClaimSet.System; }
        }

        public string Id
        {
            get { return _id.ToString(); }
        }
    }
}



e。 以下是CustomPrincipal类:

namespace CentralServicesHost
{
    class CustomPrincipal : IPrincipal
    {
        IIdentity _identity;
        string[] _roles;

        public CustomPrincipal(IIdentity identity)
        {
            _identity = identity;
        }

        // helper method for easy access (without casting)
        public static CustomPrincipal Current
        {
            get
            {
                return Thread.CurrentPrincipal as CustomPrincipal;
            }
        }

        public IIdentity Identity
        {
            get { return _identity; }
        }

        // return all roles
        public string[] Roles
        {
            get
            {
                EnsureRoles();
                return _roles;
            }
        }

        // IPrincipal role check
        public bool IsInRole(string role)
        {
            EnsureRoles();
            return (_roles != null) ? _roles.Contains(role) : false;
        }

        // read Role of user from database
        protected virtual void EnsureRoles()
        {
            using (var s = new SupportedMaterialsSystemEntities())
            {
                _roles = new string[1] { "admin" };
            }
        }
    }
}

F。 以下是我的php客户端代码:

<?php
$options = array('soap_version' => SOAP_1_2, 
                  'login'      =>  'test',
                  'password'   =>  'test');
$wsdl = "http://localhost:8080/AdminServicesSystem";
$client = new SoapClient($wsdl, $options);
$obj = new stdClass;
$obj->x = 3;
$obj->y = 3;
$retval = $client->Add($obj);//here the browser loops for infinite without any response.
//var_dump($exc);//THIS POINT NOT REACHED
//die();
$result = $retval->AddResult;
echo $result;

笔记:
1.我的操作系统是Win。 8.1,并且我正在使用Visual Studio 2013(作为管理员)和php Wamp Server。
2.我尝试了两种,都将wcf服务托管在IIS 6.2和控制台应用程序中,但是没有一个改变了我的php客户端循环。
3.我已经在将其存储在本地计算机中的IIS管理器中创建了自签名证书。
4.当我改变soap_version在php代码从SOAP_1_2SOAP_1_1Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'. Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'.

最后说明:
我的.Net C#客户端代码如下:

 using (var svcProxy = new AdminServiceProxy.AdminServicesSystemClient())
        {
            svcProxy.ClientCredentials.UserName.UserName = "test";
            svcProxy.ClientCredentials.UserName.Password = "test";
            Console.WriteLine(svcProxy.Add(1, 1));//the service works fine and print 2
        }
 }


因此,从php调用安全的wcf(带有wsHttpBinding )服务的正确方法是什么。

我相信您需要发布默认的WSDL元数据才能使用PHP soap客户端(请参阅此处的功能http://php.net/manual/en/intro.soap.php )。

尝试添加具有basicHttpBinding绑定的终结点,该绑定可以为您的客户端提供WSDL,然后使用此终结点。

在地址http:// localhost:8080 / AdminServicesSystem上,您具有带有mexHttpBinding终结mexHttpBinding ,该终结mexHttpBinding提供了其他格式的元数据( http://www.w3.org/TR/2009/WD-ws-metadata-exchange-20090317/ ) 。

尝试在此处查看表单的更多详细信息: https : //abhishekdv.wordpress.com/2013/05/24/mexhttpbinding-vs-wsdl/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM