WCF身份validation – validation邮件的安全性时发生错误

我在使用clientCredentialType="UserName"连接到我的WCF服务时遇到问题。

当我运行下面的代码时,我收到一个错误

FaultException:validation消息的安全性时发生错误。

当玩一些绑定值时,我也得到Access is denied.

Fiddler说没有授权标题,我也无法在请求中找到用户名或密码。

以下是我配置的摘录:

                                    

我的用户名/密码validation器如下所示:

  public class UserAuthentication : UserNamePasswordValidator { public override void Validate(string userName, string password) { EntitiesContext db = new EntitiesContext(); db.Logs.Add(new DomainModels.Log() { DateLogged = DateTime.Now, Message = "hit auth", Type = DomainModels.LogType.Info }); db.SaveChanges(); try { if (userName == "test" && password == "test123") { Console.WriteLine("Authentic User"); } } catch (Exception ex) { throw new FaultException("Unknown Username or Incorrect Password"); } } } 

我将此作为对我服务的简单测试:

 [OperationContract] [XmlSerializerFormat] void Test(); [PrincipalPermission(SecurityAction.Demand, Name = "test")] public void Test() { } 

我的服务器上有自签名的SSL证书,我可以访问我的服务/元数据。

然后我在控制台应用程序中添加了一个服务引用,并尝试使用以下代码连接到该服务:

 class Program { static void Main(string[] args) { Stuff.InitiateSSLTrust(); BasicHttpBinding binding = new BasicHttpBinding(); binding.Security.Mode = BasicHttpSecurityMode.Transport; binding.Security.Transport.Realm = "MyRealm"; ServiceReference1.MobileAPIClient serviceProxy = new ServiceReference1.MobileAPIClient(binding, new EndpointAddress("https://xx.xx.xx.xx/InventoryServices.MobileApi.svc")); serviceProxy.ClientCredentials.UserName.UserName = "test"; serviceProxy.ClientCredentials.UserName.Password = "test123"; try { var a = serviceProxy.Login("a", "b"); } catch (Exception ex) { var ex2 = ex; } } } public class Stuff { public static void InitiateSSLTrust() { try { //Change SSL checks so that all checks pass ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback( delegate { return true; } ); } catch (Exception ex) { } } } 

我检查了服务器上的事件查看器,每个请求都会出现此错误:

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

您指定客户端使用BasicHttpSecurityMode.Transport而服务期望BasicHttpSecurityMode.TransportWithMessageCredential 。 这是一个问题,因为服务正在SOAP消息头中查找客户端凭据,并且客户端不会使用以这种方式配置的绑定发送它们。

因此,这就是您正在目击的消息标题中不存在用户名/密码对的原因。 因此,事件查看器是正确的,通信方之间存在绑定不匹配。

还要将客户端上的ClientCredentialType设置为BasicHttpMessageCredentialType.UserName以用于Message级别安全性。 默认情况下, BasicHttpBinding使用None作为匿名客户端。

以下是描述上述更改的代码段:

 var basicHttpBinding = new BasicHttpBinding( BasicHttpSecurityMode.TransportWithMessageCredential); basicHttpBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;