WCF安全认证
我有一个简单的服务,我尝试设置身份验证。在客户端上,我希望用户输入他们的 Windows 用户帐户。 WCF 将使用客户端提供的用户名/密码并根据 Windows 身份验证对其进行身份验证。
这是我的服务器 app.config
<system.serviceModel>
<services>
<service name="WcfService.Service1" behaviorConfiguration="WcfService.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfService/Service1/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding" contract="WcfService.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService.Service1Behavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode = "Windows"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
这是我的客户端 app.config
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security mode = "Message">
<message clientCredentialType = "UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8731/Design_Time_Addresses/WcfService/Service1/"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="ServiceReference1.IService1" name="WSHttpBinding_IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
这是我在客户端上的代码
ServiceReference1.Service1Client client = new WcfAuthentication.ServiceReference1.Service1Client();
client.ClientCredentials.UserName.UserName = "mywindowsusername";
client.ClientCredentials.UserName.Password = "mywindowsuserpassword";
Console.WriteLine(client.GetData(5));
但我总是收到此异常:
{“安全通道无法打开,因为与远程端点的安全协商失败。这可能是由于用于创建通道的 EndpointAddress 中缺少或错误指定 EndpointIdentity,请验证 EndpointAddress 指定或暗示的 EndpointIdentity 是否正确标识远程端点。 {“安全令牌请求包含无效或格式错误的元素。”}
I have a simple service and I try to set up authentication. On the client I want the user to enter their Windows user account. And the WCF will use the username/password provided by the client and authenticate them against Windows authentication.
Here is my server app.config
<system.serviceModel>
<services>
<service name="WcfService.Service1" behaviorConfiguration="WcfService.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfService/Service1/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding" contract="WcfService.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService.Service1Behavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode = "Windows"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Here is my client app.config
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security mode = "Message">
<message clientCredentialType = "UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8731/Design_Time_Addresses/WcfService/Service1/"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="ServiceReference1.IService1" name="WSHttpBinding_IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Here is my code on the client
ServiceReference1.Service1Client client = new WcfAuthentication.ServiceReference1.Service1Client();
client.ClientCredentials.UserName.UserName = "mywindowsusername";
client.ClientCredentials.UserName.Password = "mywindowsuserpassword";
Console.WriteLine(client.GetData(5));
But I'm always getting this exception :
{"Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. "}
{"The request for security token has invalid or malformed elements."}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看起来您分别(手动)生成了服务和客户端配置。使用 svcutil 或 Visual Studio 的“添加服务引用”从服务生成客户端配置通常是一个好主意。这样您就知道您获得了与服务配置相对应的客户端配置。
您想要的是可能的,但 WCF 不允许您在使用
wsHttpBinding
时以纯文本形式传输用户名/密码令牌。这意味着您必须使用 https 托管服务或使用服务证书。 此处' sa 帖子有更多细节。但我也想知道为什么你会想要这样的东西。使用集成 Windows 身份验证可能是一个更好的主意。这甚至是 wsHttpBinding 的默认设置。这样您就不需要客户输入他们的 Windows 用户名/密码。
It looks like you generated the service and client configuration separately (by hand). It usually is a good idea to generate the client configuration from the service using
svcutil
or Visual Studio's 'Add Service Reference'. This way you know that you get the client config that corresponds to the service config.What you want is possible, but WCF doesn't allow you to transmit your username/password token in plain text when using
wsHttpBinding
. This means that you must either host your service using https or use a service certificate. Here's a post with some more details.But I'm also wondering why you would want anything like this. It may be a better idea to use integrated Windows authentication. This is even the default setting for
wsHttpBinding
. This way you do not need your client(s) to enter their Windows username/password.我认为使用 WsHttpBinding 的 Windows 身份验证仅适用于 https。
请参阅:http://msdn.microsoft.com/en-us/library /ff650619.aspx
I think Windows Authentication with WsHttpBinding only works with https.
See this: http://msdn.microsoft.com/en-us/library/ff650619.aspx