我同意@ John的回答,即使用一次性令牌比存储凭据要好。
对于令牌,您可以生成一些随机GUID并将其存储在数据库中。
作为不需要ASP.NET应用程序和WCF服务之间协调的替代方法,您可以将签名文档作为标记发送。
- 使用带符号时间,用户名和签名者名称(ASP.NET应用程序)创建XML或JSON文档。
- 生成上述文件的散列。
- 使用非对称加密(使用私钥)签名哈希。
WCF所要做的就是验证散列和签名。所以这不涉及到同一个数据库。使用签名时间,您可以在固定时间内过期令牌。
编辑:这个想法是基于public-key cryptography(也称为非对称密钥算法,公钥/私钥)。如果使用私钥加密某些内容,则只能使用相应的公钥将其解密;并且如果使用公钥对某些内容进行加密,则只能使用相应的私钥对其进行解密。有关代码在C#中的外观,请参阅Implementing RSA in C#。为什么这很有用?因为我们可以用它来实现数字签名。数字签名是证明我和我只写了一些东西,而不是其他人的一种方式。
继上述步骤生成的签名。你首先需要定义一个“让这个人在”文档中的规范形式。通常,非对称密钥算法无法处理太大的输入,因此您可以使用您的ASP.NET应用程序的专用密钥来加密哈希。生成的签名只能使用您的应用程序的公钥解密。最后,您可以将所有三个组件(原始文档,散列和签名)打包为XML或JSON等格式,并将其作为标记发送。
举个例子,假设你使用JSON格式的一切。首先,原来的“让这个家伙在文件”:
{"UserName":"Foo","SignedTime":"2009-07-09T00:00:00","Signer":"ASP.NET APP1"}
接下来,生成上面的字符串,这是byte[]
的SHA-1散列与modified Base64 encoding什么编码它,它看起来是这样的:
b2YgYW55IGNhcm5hbCBwbGVhc3VyZS4
以上是虚假字符串,实际的东西可能看起来更长。然后,取散byte[]
和使用RSA,生成另一个byte[]
所以编码也有修改的Base64编码加密它:
mxlIGdlbmVyYXRpb24gb2Yga25vd2xfo34
最后,你再拍JSON文件来存储所有以上。
{"UserName":"Foo","SignedTime":"2009-07-09T00:00:00","Signer":"ASP.NET APP1","Hash":"b2YgYW55IGNhcm5hbCBwbGVhc3VyZS4","Signature":"mxlIGdlbmVyYXRpb24gb2Yga25vd2xfo34"}
最终的JSON文件成为你的密码的令牌。将它传递给WCF服务。 WCF服务取令牌,通过消除散列和签名构造原始文件:
{"UserName":"Foo","SignedTime":"2009-07-09T00:00:00","Signer":"ASP.NET APP1"}
按照相同的算法来生成散列并验证它是相同的。使用ASP.NET应用程序的公钥解密签名,看看它是否成为哈希。此时,该文件被验证是由签名者签署的。检查当前时间和签名时间,看看令牌是否仍然有效。您所需要的只是在两个代码库之间分配公钥的方法,这些代码库可以从XML加载。
请说明downvote的原因。如果没有人说错误是错误的,那么从错误中学习是不可能的。 – 2009-07-03 14:37:12
你建议的方法听起来非常适合我的情况,但我对如何实现这一细节不清楚:1)如果WCF服务应该实现一个明确的登录方法验证用户名和密码,并返回认证令牌? 2)客户端凭证类型应该是什么? 3)什么是在后续请求中传递身份验证令牌的推荐机制(例如,作为每个服务方法的显式参数,或者像使用UserName认证时的用户名和密码那样的“幕后”)。 – AJM 2009-07-05 17:43:26