使用PasswordText的WCF Soap Header

时间:2014-05-08 16:49:38

标签: c# wcf windows-8.1

我们正在开发一个访问WCF服务的Windows 8商店应用程序。对于安全性,SVC具有提供的凭据以访问那里可用的每种方法。密码类型已设置为PasswordText。当我尝试访问WCF时,我收到错误“验证邮件的安全性时出错。”我的客户端代码如下:

CustomBinding binding = new CustomBinding();
binding.SendTimeout = TimeSpan.FromMinutes(2);
binding.OpenTimeout = TimeSpan.FromMinutes(2);
binding.CloseTimeout = TimeSpan.FromMinutes(2);
binding.ReceiveTimeout = TimeSpan.FromMinutes(10);
binding.Elements.Add(new TextMessageEncodingBindingElement( MessageVersion.Soap12WSAddressing10, System.Text.Encoding.UTF8));
binding.Elements.Add(new HttpTransportBindingElement());
binding.Name = "ClearUsernameBinding_IUserDetailsService";

EndpointAddress endpoint = new EndpointAddress(new Uri("http://MyURL"));
ServiceReference1.UserDetailsServiceClient proxy = new ServiceReference1.UserDetailsServiceClient(binding, endpoint);

proxy.Endpoint.Contract.Name = "IScheduledVisitsService";
proxy.Endpoint.Contract.ConfigurationName = "ClearUsernameBinding_IScheduledVisitsService";
proxy.Endpoint.Address = endpoint;
proxy.Endpoint.Binding = binding;
proxy.ClientCredentials.UserName.UserName = Loginmodel.UserName;
proxy.ClientCredentials.UserName.Password = Loginmodel.Password;
UserDTO result =  await proxy.GetUserByUsernameAsync(Loginmodel.UserName);   

似乎密码必须设置为PasswordText,任何想法如何解决

2 个答案:

答案 0 :(得分:1)

以下是我为了让它发挥作用所做的事情:

            CustomBinding binding = new CustomBinding();

            binding.Name = "ClearUsernameBinding_IUserDetailsService";

            binding.SendTimeout = TimeSpan.FromMinutes(2);
            binding.OpenTimeout = TimeSpan.FromMinutes(2);
            binding.CloseTimeout = TimeSpan.FromMinutes(2);
            binding.ReceiveTimeout = TimeSpan.FromMinutes(10);
            binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, System.Text.Encoding.UTF8));
            binding.Elements.Add(TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement());
            binding.Elements.Add(new HttpsTransportBindingElement());


            EndpointAddress endpoint = new EndpointAddress(new Uri("https://MYURL"));
            ServiceReference1.UserDetailsServiceClient proxy = new ServiceReference1.UserDetailsServiceClient(binding, endpoint);

            proxy.Endpoint.Contract.Name = "IScheduledVisitsService";
            proxy.Endpoint.Contract.ConfigurationName = "ClearUsernameBinding_IScheduledVisitsService";
            proxy.Endpoint.Address = endpoint;
            proxy.Endpoint.Binding = binding;
            proxy.ClientCredentials.UserName.UserName = Loginmodel.UserName;
            proxy.ClientCredentials.UserName.Password = Loginmodel.Password;
            UserDTO result = await proxy.GetUserByUsernameAsync(Loginmodel.UserName);

如果在config

中完成,则相当于以下内容
    <binding name="myBinding">
      <security defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport"
        requireDerivedKeys="true"
        includeTimestamp="true"
        messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
      </security>
      <textMessageEncoding messageVersion="Soap11" />
    </binding>`

但是像SuMMeR所说,这只适用于HTTPS。如果要允许不安全,可以将allowInsecureTransport="true"添加到配置文件中的<security>元素。如果您想在代码中执行此操作,我认为您可以尝试以下操作:

TransportSecurityBindingElement mySecElement = new TransportSecurityBindingElement {  AllowInsecureTransport = true };
binding.Elements.Add(mySecElement);

答案 1 :(得分:0)

默认情况下,不允许在WCF中以不安全的方式发送客户端凭据。请看下面的一些如何保护您的服务:

Transport Security

Message Security

还有一个workarownd允许通过HTTP发送未加密的客户端凭据: SecurityBindingElement.AllowInsecureTransport。但是你不应该在生产中使用它,因为它会带来严重的安全漏洞。