ASP.NET 是自.NET 1.x 就已经有的技术,利用IIS+ASP.NET 搭建的网站已经有很多。针对IIS+ASP.NET 的网站模型也有很多案例,通过现在的搜索服务我们可以很轻易的获取这些内容。
大家可能很熟悉如何使用窗体认证,Windows认证,用户名/密码, SQL Server 等认证技术/服务来实现IIS + ASP.NET 站点的认证,而现在我们要讨论的是如何使用ASP.NET 来对WCF 服务进行验证。
现在,我们直接进入主题...
我们要讨论的模型简化的说就是WCF + 证书 + 消息认证 + Membership Provider, 具体说来就是WCF服务使用证书对通信过程加密,然后服务端对消息解密并通过Membership Provider 对解密的消息(用户名/密码)进行验证。
请看如下截图:
图片1-1 WCF 消息认证 + SqlMembership Provider 认证
接下来我们就如何构建WCF 消息认证 + SqlMembership Provider 认证给出一个具体的实施步骤。
第一步: 创建WCF IIS 服务
创建一个新的网站->选择 WCFService->将其命名为 service
第二步: 配置Solution.
图片1-2 Solution 配置
1 [ServiceContract]
2 public interface IService
3 {
4 [OperationContract]
5 string GetData( int value);
6 [OperationContract]
7 CompositeType GetDataUsingDataContract(CompositeType composite);
8 // TODO: Add your service operations here
9 }
10 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
11 public class myService : IService
12 {
13 public string GetData( int value)
14 {
15 return string .Format( " You entered: {0} " , value);
16 }
17 }
第三步: 创建Form 认证数据库(Membership Provider 使用表单认证模式)
转到C:\WINDOWS\Microsoft.NET\Framework\<versionNumber>\aspnet_regsql.exe,双击运行aspnet_regsql.exe,
按步骤保留默认配置即可。
如果有不清楚的部分请参考http://msdn.microsoft.com/en-us/library/x28wfk74.aspx
第四步: 创建证书
我们借助Windows 自带的Makecert.exe 证书生成工具生成证书。
打开命令行窗口,输入:
makecert -r -pe -n "CN=www.yourserver.com" -b 01/01/2000 -e 01/01/2036 -eku 1.3.6.1.5.5.7.3.1
-ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider"
-sy 12
可以参考http://www.inventec.ch/chdh/notes/14.htm
第五步: 配置IIS Host 服务 web.config 文件
首先是连接字符串部分:
1 < connectionStrings >
2 < clear />
3 < add name ="LocalSqlServer" connectionString ="Data Source=DANIELFACTORY2;
4 Initial Catalog=aspnetdb;Integrated Security=True" />
5 </ connectionStrings >
注意要将连接字符串中对应的值更改,使其匹配个人环境配置,aspnetdb 为第三步生成的默认数据库。
第六步: 在IIS Host 服务web.config 文件中创建Membership Provider
1 < membership defaultProvider ="membership" >
2 < providers >
3 < add name ="membership" type ="System.Web.Security.SqlMembershipProvider,
4 System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
5 connectionStringName ="LocalSqlServer" enablePasswordRetrieval ="false"
6 enablePasswordReset ="true" requiresQuestionAndAnswer ="true" applicationName ="/"
7 requiresUniqueEmail ="false" passwordFormat ="Hashed" maxInvalidPasswordAttempts ="5"
8 minRequiredPasswordLength ="7" minRequiredNonalphanumericCharacters ="1"
9 passwordAttemptWindow ="10" passwordStrengthRegularExpression ="" />
10 </ providers >
11 </ membership >
12 < authentication mode ="Forms" />
也可以使用自定义SqlMembershipProvider,注意connectionStringName与第五步中创建的名字要匹配。
第七步: 为IIS Host 服务配置完成的web.config 文件
配置完成后要检查以下几项配置:
1)消息认证类型(Message credential type) == UserName
2)服务协商凭据(negotiate Service credential) == false
3)服务证书
4)UserNameAuthentication->UserNamepasswordvalidatormode=MembershipProvider
&& MembershipProviderName == membership.
在我的例子中 membership provider 的名字是membership.
5) 检查证书指纹
http://msdn.microsoft.com/en-us/library/ms734695.aspx.
6) 打开IIS Site Manager,为我们的IIS Host 服务新建一个站点。
图片1-3 创建IIS Site
7) 为我们的IIS Host Site 设定认证模式
图片1-4 设置IIS Site 认证模式
8) 确定服务已经成功启动
第八步: 创建一个新的控制台应用程序作为客户端
第九步: 利用添加服务引用功能为客户端添加服务引用
图片1-5 生成客户端代理
第十步: 客户端代码
至此,你可以运行一下服务端和客户端,初步看一下结果,但是很不幸,你会得到下面的错误:
图片1-6 客户端运行错误信息
说实话,产生这个错误的原因非常多,但从字面意思看是由于没有建立安全连接导致的。实际上微软为了防止攻击者知道太多具体的错误信息,大多对类似的错误信息进行了包装。
这个错误的真正原因可能是用户名/密码不正确,也可能是配置错误,但是如果直接报出用户名不正确/密码错误的异常信息,那么对攻击者来说岂不是太方便了?!
但是我们如何才能知道底层错误到底是由什么引起的呢?
其实,这个问题才是我们真正应该学习和了解掌握的,我们之前在服务端配置了诊断信息,所以现在我们可以到相关log 文件中找一下错误原因:
图片1-7 WCF Membership Provider 具体验证错误信息
这个错误说明我们在客户端提供的用户名/密码验证失败。
那么我们现在需要想一下,到目前为止,除了在客户端设置密码以外,我们未曾在任何地方设置用户名/密码,那么问题可能是由于我们还未设置认证信息导致的,也就是说我们还没有建立信息认证中心(这个称呼着实有些大,很吓人)。
回到之前,我们通过aspnet_regsql.exe 生成aspnetdb 的过程,打开这个数据库我们就可以知道用户名/密码是存在这里面的,但是如何将用户信息加入这个表内呢? 你是不是想通过SQL 语句? 哈哈,我一开始也是这么想的!
但是,不要忘了,我们现在还不了解这个数据库中各个表项的关联关系,这么加只会导致牛毛越来越多,那么如何解决问题呢?很遗憾,不要想着通过Google, Baidu 来搜索答案,这个问题在网上没有任何有价值的信息,关键时刻还得靠我们自己!!!
现在,我们还是回到Visual Studio,执行如下操作:
图片1-8 ASP.NET Configuration 配置
单击图片框中的图标,我们将得到以下界面
图片1-9 ASP.NET Site 配置界面
依次转到Security->Users->Create User->创建用户
图片1-10 创建新用户
图片1-11 用户创建成功
接下来,好好享受你的WCF 之旅吧 :)