rity 绑定协议:.WSHTTPBinding。我会把如何在XP环境下设置可信证书的过程,详细的描述出来。因为这个错误就是和证书有直接关系,对于很多XP环境下进行WCF编程的学习者来说,应该有不错的参考价值。错误信息:The caller was not authenticated by the service。服务验证调用者失败。XP系统配置证书还似乎比较麻烦,你像Windows服务器系列,我们可以建立CA来控制证书的状态。虽然我们可以自己安装。但是过于麻烦。正如申请一个免费的证书一样。仅仅为了个人学习,一切都希望简单,快速地学习WCF的安全编程。我这里也是使用了makecert制作的证书。
设置了服务器证书,消息安全模式。 我搜索的资料。如下:
The caller was not authenticated by the service - WCF Security using ...
The caller was not authenticated by the service
Caller was not authenticated by the service
WCF - The caller was not authenticated by the service
WCF - TCP+Cert "The caller was not authenticated by the service." 但是没什么帮助,类似的问题很多都是没有解决。问题我也放到WCF中文和英文论坛:设置了服务器证书,消息安全模式。 我搜索的资料。如下:
http://social.microsoft.com/Forums/zh-CN/wcfzhchs/thread/cd3f0247-a1b4-43c0-af1c-7b0e609b1e3b
http://social.microsoft.com/Forums/zh-CN/wcf/thread/3a5417c6-fdd1-47d7-9757-ebc8ede7affb。
【1】问题描述: 错误信息的截图:
一样采用UserNamePasswordValidator验证方式。wsHttpBinding,此绑定支持WS安全规范。必须启动服务端证书。 WCF分布式开发常见错误(21):unable to open its IChannelListener.分发器未能打开侦听器 ,已经遇到过一次了问题。当时导致错误的原因是没有启用服务端证书。 这个错误修正完毕以后,再次启动服务,添加服务引用,生成了客户端代理等相关文件。 服务行为的证书配置信息如下:
<serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate x509FindType="FindBySubjectName" findValue="MyServer" storeLocation="CurrentUser"/>
<clientCertificate >
<authentication certificateValidationMode="None" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFService.MyUserNamePasswordValidator,WCFService" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate x509FindType="FindBySubjectName" findValue="MyServer" storeLocation="CurrentUser"/>
<clientCertificate >
<authentication certificateValidationMode="None" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFService.MyUserNamePasswordValidator,WCFService" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
这句话就是服务端查询证书的依据:<serviceCertificate x509FindType="FindBySubjectName" findValue="MyServer" storeLocation="CurrentUser"/>。在CurrentUser位置,查找主题为MyServer的证书。
使用x509证书是符合WS安全规范。证书是非对称加密算法的典型应用。至于如何获得非对称加密、证书,我在之前的系列文章里已经详细讲过,需要的话可以再参考:WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理
使用x509证书是符合WS安全规范。证书是非对称加密算法的典型应用。至于如何获得非对称加密、证书,我在之前的系列文章里已经详细讲过,需要的话可以再参考:WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理
【2】问题分析:
从异常信息来看:The caller was not authenticated by the service。服务验证调用者失败。在看看验证的代码:
if (userName != "FrankXuLei" || password != "12345678")
{
Console.WriteLine("UserNamePasswordValidatation is sucessfully !:{0}", userName);
//throw new SecurityTokenException("Unknown Username or Password");
}
else
{
Console.WriteLine("UserNamePasswordValidatation is failed !:{0}", userName);
}
{
Console.WriteLine("UserNamePasswordValidatation is sucessfully !:{0}", userName);
//throw new SecurityTokenException("Unknown Username or Password");
}
else
{
Console.WriteLine("UserNamePasswordValidatation is failed !:{0}", userName);
}
猜测一下可能的原因:
(1)UserName 错误,这里用户名不等于FrankXuLei,也会导致验证失败。
(2)Password错误,这里密码不等于12345678,同样也会导致验证失败。
(3)加密和解密出现了问题,这个是可能的原因,虽然我们使用了证书,难说不会出现错误。比如使用了错误的服务端公钥加密。
(4)其它原因,这个原因很难想到,居然是证书未受信任导致的。 这个原因比较诡异。我也是几乎崩溃的时候才想到的。查询了很多资料,基本都对不上,国内的技术文章基本都是直接贴代码,然后是一对分析,至于能不能执行就另外来说了。我相信很多自学WCF编程的朋友,也会遇到这个问题。
【3】解决办法:
你然找到的问题的原因,就想办法来解决。下面的步骤就是如何使的自己制作的服务器证书编程可信任。
(1)UserName 错误,这里用户名不等于FrankXuLei,也会导致验证失败。
(2)Password错误,这里密码不等于12345678,同样也会导致验证失败。
(3)加密和解密出现了问题,这个是可能的原因,虽然我们使用了证书,难说不会出现错误。比如使用了错误的服务端公钥加密。
(4)其它原因,这个原因很难想到,居然是证书未受信任导致的。 这个原因比较诡异。我也是几乎崩溃的时候才想到的。查询了很多资料,基本都对不上,国内的技术文章基本都是直接贴代码,然后是一对分析,至于能不能执行就另外来说了。我相信很多自学WCF编程的朋友,也会遇到这个问题。
【3】解决办法:
你然找到的问题的原因,就想办法来解决。下面的步骤就是如何使的自己制作的服务器证书编程可信任。
(1)制作证书:这里直接使用makecert 工具。Microsoft Visual Studio 2008-->Visual Studio Tools-->Visual Studio 2008 命令提示行里输入:
makecert -r -pe -n "CN=FrankWCFServer" -ss My -sky exchange
具体大家可以看文章WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理,详细的介绍。具体的参数说明:详细帮助文档:http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cptools/html/cpgrfcertificatecreationtoolmakecertexe.asp
makecert -r -pe -n "CN=FrankWCFServer" -ss My -sky exchange
具体大家可以看文章WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理,详细的介绍。具体的参数说明:详细帮助文档:http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cptools/html/cpgrfcertificatecreationtoolmakecertexe.asp
(2)导出证书:
这里要借助IE浏览器,此例以IE7为准,其它版本功能类似,可能界面有差异。具体步骤:
打开浏览器---->Internet 选项----->内容----->证书----->个人,你会看到刚才制作的证书。如图:
选择导出,保存为一个证书
这里是不包含私钥的二进制X.509证书文件。这里要借助IE浏览器,此例以IE7为准,其它版本功能类似,可能界面有差异。具体步骤:
打开浏览器---->Internet 选项----->内容----->证书----->个人,你会看到刚才制作的证书。如图:
(3)导入证书:
使用向导,在受信任的根证书机构里导入证书:
(4)测试证书:
此时刚才创建的FrankWCFServer证书,就可以使用了,我们启动WCF服务宿主,运行客户端,设置用户名和密码以后,调用方法成功!解决了上诉问题。
【4】总结:
WCF安全编程相对来多复杂了很多。WCF提升了安全级别。在WCF分布式开发常见错误(21):unable to open its IChannelListener.分发器未能打开侦听器最后和Robin Zhang 还有 不若相忘于江湖 讨论过这个问题。
我之前也有关于这个问题的疑惑。因为之前Web Service 和 WSE3.0 里都可以使用用户名和密码方式来实现身份验证。Web Service可以直接在Soap 消息头部加入UserName 和Password信息。WSE3.0对此进行了扩展,加入了安全验证机制,要求客户端在服务调用以前,必须设置用户令牌信息,服务获取请求以后,先进行消息的还原和验证。WCF里的UserNamePasswordValidator验证方式应该就是对扩展。不过他是重写了UsernameTokenManager的AuthenticateToken方法。但是机制应该类似。大家有兴趣可以看看WSE3.0构建Web服务安全(1):WSE3.0安全机制与实例开发 。
希望这个文章对希望简化Xp下WCF安全编程的朋友一些帮助。正在整理WCF安全的文章。代码也已经调试完毕。
参考文章:
1.WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理
2.http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cptools/html/cpgrfcertificatecreationtoolmakecertexe.asp
此时刚才创建的FrankWCFServer证书,就可以使用了,我们启动WCF服务宿主,运行客户端,设置用户名和密码以后,调用方法成功!解决了上诉问题。
【4】总结:
WCF安全编程相对来多复杂了很多。WCF提升了安全级别。在WCF分布式开发常见错误(21):unable to open its IChannelListener.分发器未能打开侦听器最后和Robin Zhang 还有 不若相忘于江湖 讨论过这个问题。
我之前也有关于这个问题的疑惑。因为之前Web Service 和 WSE3.0 里都可以使用用户名和密码方式来实现身份验证。Web Service可以直接在Soap 消息头部加入UserName 和Password信息。WSE3.0对此进行了扩展,加入了安全验证机制,要求客户端在服务调用以前,必须设置用户令牌信息,服务获取请求以后,先进行消息的还原和验证。WCF里的UserNamePasswordValidator验证方式应该就是对扩展。不过他是重写了UsernameTokenManager的AuthenticateToken方法。但是机制应该类似。大家有兴趣可以看看WSE3.0构建Web服务安全(1):WSE3.0安全机制与实例开发 。
希望这个文章对希望简化Xp下WCF安全编程的朋友一些帮助。正在整理WCF安全的文章。代码也已经调试完毕。
参考文章:
1.WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理
2.http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cptools/html/cpgrfcertificatecreationtoolmakecertexe.asp
本文转自 frankxulei 51CTO博客,原文链接:http://blog.51cto.com/frankxulei/320446,如需转载请自行联系原作者