cnlan

导航

WCF安全模式:基于用户名、密码、X.509的身份验证

X.509 比较适合验证 "客户机" 的身份,而另外一方面,我们可能需要针对具体的 "用户" 进行验证。

1.首先我们需要一个数字证书。

开始>>程序>>Microsoft Visual Studio 2008>>Visual Studio Tools>>Visual Studio 2008 Command Prompt

makecert -r -pe -n "CN=CACert" -sr LocalMachine -ss My -sky exchange

其实 LocalMachine 代表我们这个证书保存在"计算机帐户"中;My表示保存在"个人"这个类别下.

开始>>运行>>mmc   启动控制台

文件>>添加/删除管理单元>>添加 中添加证书的管理,帐户为"计算机帐户",管理单元管理的计算机为"本地计算机"

然后如下图可见,我们在"个人>>证书"目录可以找到我们刚才生成的证书"CACert".双击这个证书我们可以查看他的信息.

 

因为我们是自己生成的证书,所以 该CA根证书不受信任.

这个不受信任给接下来的工作制造了很多麻烦,我不知道高手是怎么解决的.

我解决的办法是先选择这个证书,右键选择"复制",然后展"开受信任的根证书颁发机构>>证书",右键点击证书,选择"粘贴".然后再查看这个人目录下的证书,这个证书就变成可以信任的了.

将来要部署的话可以导出这个证书,去其他机器上安装.

 

 

当然,这样做还是不够的.在以后的验证中,会发现IIS没有权限去读取这个证书的密钥.老是提示"密钥集不存在。".为了克服这个问题,我们需要分配一些权限.

在XP中我们给ASPNET这个帐户分配权限就可以了,再2003中,我们需要给NT AUTHORITY\NETWORK SERVICE这个帐户分配一些权限.

我们找个工具帮组我们一下:FindPrivateKey.exe

安全期间,还是自己去下一个比较好.

他可以帮我们找到我们密钥的位置。

 

 这是我输入了2次命令,区别就在最后的“-a”上,只是改变了下显示方式。后面要用到。

FindPrivateKey.exe My LocalMachine -t "a5 16 2b be 74 b1 ea 39 fb 3f 2c bc b7 db f3 42 8a a3 17 60"

My LocalMachine 表示证书的安装位置,"a5 16 2b be 74 b1 ea 39 fb 3f 2c bc b7 db f3 42 8a a3 17 60"是证书的“微缩图”,查看证书的”详细信息“里面可以看到。

然后我们按照查询的结果,找到这个文件,然后设置权限。当然我们用 cacls.exe 这个Windows这个自带的工具也可以。大家可以看下一个批处理文件。

@echo off
echo 
************
echo setting privileges on server certificates
echo 
************
for /"delims=" %%in ('FindPrivateKey.exe My LocalMachine -t "a5 16 2b be 74 b1 ea 39 fb 3f 2c bc b7 db f3 42 8a a3 17 60" -a'do set PRIVATE_KEY_FILE=%%i
set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE
(ver 
| findstr /C:"5.1"&& set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
echo 
%WP_ACCOUNT%
echo Y
|cacls.exe "%PRIVATE_KEY_FILE%" //"%WP_ACCOUNT%":R
pause


证书的准备到这里基本就没什么问题了。 不过实际运用的时候,还是找个比较可靠的证书,这个工具生成的我不太放心。

2.用户名,密码验证

我们需要引用System.IdentityModel这个空间的内。他在位置在

C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.dl

然后我们可以在服务中添加一个验证用的类 :MyUserNamePasswordValidator

Code


然后我们可以在web.config 中做一些配置

    <system.serviceModel>
        
<bindings>
            
<wsHttpBinding>
                
<binding name="BooksServiceBinding">
          
<security mode="TransportWithMessageCredential">
            
<message clientCredentialType="UserName"/>
          
</security>
                
</binding>
            
</wsHttpBinding>
        
</bindings>
        
<services>
            
<service behaviorConfiguration="ServiceBehavior" name="WCFCAcertTest.Service.Service">
                
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="BooksServiceBinding" contract="WCFCAcertTest.Contract.IService"/>
            
</service>
        
</services>
        
<behaviors>
   
<serviceBehaviors>
    
<behavior name="ServiceBehavior">
     
<serviceMetadata httpGetEnabled="true" />
     
<serviceCredentials>
      
<serviceCertificate findValue="0593589181bedb74f42cd84433a82c4984ecd7d1"
       storeLocation
="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
       
<clientCertificate>
         
<authentication certificateValidationMode="None"/>
       
</clientCertificate>
       
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFCAcertTest.Service.MyUserNamePasswordValidator,WCFCAcertTest.Service"/>
     
</serviceCredentials>
    
</behavior>
   
</serviceBehaviors>
  
</behaviors>
    
</system.serviceModel>


加下划线的地方要注意下,其中 indValue="0593589181bedb74f42cd84433a82c4984ecd7d1"换成你证书的“微缩图”,中间需要去掉空格。

基本上没有什么问题了。

传一个我做的测试程序。WCFCAcertTest.rar

posted on 2009-11-06 20:29  小菜猪  阅读(393)  评论(0编辑  收藏  举报