代码改变世界

WCF 第八章 安全 传输层安全

2011-01-07 18:14  DanielWise  阅读(1449)  评论(0编辑  收藏  举报

传输层安全,正如它的名字所暗示的,在客户端和服务端的通信信道中提供安全。这个层次的安全可以包含加密和认证。信道栈(绑定)确定加密类型以及可用的认证协议。

  在最低限度,传输层安全确保通信在客户端和服务端之间是加密的以便于只有客户端和服务端可以理解交换消息。用来加密的特殊算法是底层协议(例如,HTTPS使用SSL)的一个函数或者可以在绑定中(MSMQ 可以使用RC4Stream或者AES)使用。

  除了加密,传输层安全可以通过在通信信道建立时请求由客户端发送给服务端的证书来包含客户端认证。证书可以是数字证书,SAML 令牌,Windows令牌或者一个共享机密比如一个用户名和密码。传输层安全也在客户端和服务端之间建立起一个安全信道前验证服务身份。这个验证保护数据免于中间人和欺骗袭击。

使用SSL加密

SSL是一个方便的,安全的方式来对通信进行加密。它很容易被IT组织理解,防火墙友好的,而且市场上有很多管理和性能工具。使用SSL + BasicHttpBinding 可以实现对一个安全网络服务的最好访问。

  SSL要求一个数字证书和一个非对称密钥(公共/私有)来建立一个加密通道。在通道建立以后,SSL使用这个通道,使用一个更加高效的对称加密算法来对在信道上传输的消息进行加密。

  可以从很多地方获取一个数字证书。有公共组织,比如威瑞信公司(http://www.verisign.com/cn/),负责提供测试和生产目的的证书。Windows 服务器本身附带了一个证书管理服务,所有你可以生成你自己的证书并在你自己的组织或者合作伙伴之间信任。额外的,.NET 附带了一个实例,MakeCert,可以生成用于测试目的的证书。

基于HTTP 的SSL

SSL可以应用于大多数传输协议上(一个明显的例外是队列协议),但是最常用的协议是HTTP。当使用一个基于HTTP传输协议的绑定时,无论你的服务通过IIS寄宿还是在另外一个进程中自我寄宿,HTTP.SYS必须配置成使用SSL。对于IIS来说,你可以使用IIS管理工具来添加绑定。对IIS7来说,这是通过选择一个定义了虚拟目录的Web 站点完成的,然后在操作面板选择绑定连接。这将运行一个对话框,通过它你可以选择用于SSL通信的证书(图片8.1)。

  在Windows Server 2003 或者Vista 上的自我寄宿服务,你可以使用netsh 工具。列表8.3 显示了使用这个工具配置HTTP.SYS来允许SSL在端口8001上通信的过程。确定IP 地址是0.0.0.0意味着所有的IP 地址。40位16进制数上本机安装的证书的指纹。指纹可以通过微软管理控制台的插件来找到并查看证书细节。最后的GUID是一个应用标识,代表了谁允许了这次访问。你在这里生成的任意GUID都是可以接受的并会与你的应用关联。

1-7-2011 2-25-51 PM

图片8.1 为SSL设置IIS7

 

列表8.3 使用Netsh 来配置HTTP.SYS以在不同端口上允许SSL

1-7-2011 5-57-56 PM

  当你已经在HTTP.SYS上注册证书以后,接下来你可以设置一个服务来使用SSL加密。列表8.4显示了一个使用basicHttpBinding绑定的服务端配置文件,传输层加密,没有客户端验证。注意在这个自我寄宿的配置文件中确定了两个基地址,一个用于加密通信另一个用于非加密通信。这允许MEX终结点使用一个非加密信道同时顺序通信都被加密。如果你不想暴露一个MEX终结点,或者如果它在一个安全信道上暴露比较好,你不需要非加密地址。

列表8.4 使用basicHttpBinding加密

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="MyBinding">
                    <security mode="Transport">
                        <transport>
                            <extendedProtectionPolicy policyEnforcement="Never" />
                        </transport>
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="metadata">
                    <serviceMetadata httpGetEnabled="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="metadata" name="EssentialWCF.EmployeeInformation">
                <endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
                    contract="EssentialWCF.IEmployeeInformation" />
                <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
                    contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8000/EffectiveWCF" />
                        <add baseAddress="http://localhost:8001/EffectiveWCF" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>

在TCP上使用SSL

与HTTP相像,TCP传输可以使用SSL来加密通信。为TCP确定的传输安全的配置选项与HTTP的类似。为了配置一个使用TCP安全的服务,必须对列表8.4中的配置做三处更改。

  首先,为非MEX终结点确定的绑定是NetTcpBinding而不是basicHttpBinding.其次,服务基地址应该是一个TCP URI 地址而不是一个HTTP URI, 以net.tcp://{hostname}[:port]/{service location}.第三,应该使用一个NetTcpBinding配置而不是basicHttpBinding配置来确定<Security mode=”transport”>设置。列表8.5显示了配置。

列表8.5 使用NetTcpBinding 加密

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="MyBinding">
                    <security>
                        <transport clientCredentialType="None">
                            <extendedProtectionPolicy policyEnforcement="Never" />
                        </transport>
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="metadata">
                    <serviceMetadata httpGetEnabled="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="metadata" name="EssentialWCF.EmployeeInformation">
                <endpoint address="" binding="netTcpBinding" bindingConfiguration="MyBinding"
                    contract="EssentialWCF.IEmployeeInformation" />
                <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
                    contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8000/EffectiveWCF" />
                        <add baseAddress="net.tcp://localhost:8002/EffectiveWCF" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>