sen

导航

学习笔记之 WCF安全(4) 集成window身份验证 (netTCP)

Posted on 2009-11-16 18:00  sen  阅读(1838)  评论(1编辑  收藏  举报

这一节将发生比较大的改动 从证书验证变为Windows验证

Host的配置文件发生了较大的变化:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WCF.Service1" behaviorConfiguration="WCF.Service1Behavior">
        <host>
          <baseAddresses>
            <!--<add baseAddress = "https://192.168.172.1:99/" /> 这里在改为 net.tcp: -->
            <add baseAddress ="net.tcp://192.168.172.1:99/"/>
          </baseAddresses>
        </host>
        <endpoint address ="myWCF" binding="netTcpBinding" contract="WCF.IService1" bindingConfiguration ="myTcpBingding">
          <!--<identity>
            <dns value="localhost"/>
          </identity>-->
        </endpoint>
        <!--<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/> -->
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCF.Service1Behavior">
          <!--<serviceMetadata httpGetEnabled="True"/> 不能httpget方式得到描述了-->
          <serviceMetadata httpGetEnabled="false"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!-- 做这个实例的时候要把证书这一块去掉,因为不需要证书来验证 -->
          <!--<serviceCredentials >-->
            <!--<serviceCertificate storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" findValue="WCFServerPK" />-->
            <!-- 加入下面一句, 指定自定义的验证方式  
            WCFHost(这个是命名空间).myValidate(这个是类名) , WCFHost(这个是工程名),其实就是指定哪个文件下面的哪个命名空间下面的验证类 -->
            <!--<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType ="WCFHost.myValidate,  WCFHost"/>--> 
          <!--</serviceCredentials>-->
          
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings >
      <!-- 这里用的是netTcpBinding  ,用TCP +集成windows验证 做安全  而不是用wcHttpBinding  +证书  -->
      <netTcpBinding >
        <binding name="myTcpBingding">
          <security mode="Transport">
            <transport clientCredentialType ="Windows" protectionLevel ="EncryptAndSign"/>
          </security>
        </binding>
      </netTcpBinding>
      <!--<wsHttpBinding >
        <binding name ="myHttpBinding">
          <security mode="Transport">
            <transport clientCredentialType ="Windows"/> --><!-- 这里改成window验证--><!--
          </security>
        </binding>
      </wsHttpBinding>-->
    </bindings>
  </system.serviceModel>
</configuration>

服务端口启动程序基本一样没有太大的改变

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/*这里没有变化 ,还是和原来一样*/
namespace WCFHost
{
    class Program
    {
        static void Main(string[] args)
        {
            using (System.ServiceModel.ServiceHost   Host  = new System.ServiceModel.ServiceHost(typeof(WCF.Service1 )))
            {
                if (Host.State != System.ServiceModel.CommunicationState.Opened)
                    Host.Open();
                Console.Write("WCF服務已打開!!!");
                Console.Read();
            }
        }
    } 
}

这里因为没有用到证书的验证 ,所以客户端的一些命名空间什么都不要, 这里新建立了一个console application作为客户端

加入service reference  在URL处用net.tcp://192.168.172.1:99/mex  ,请注意要加上mex 这个endpoint 名  ,把引用名改为myWCF  

代码中只需要如下几句便可以进行访问:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TCPWCFClient
{
    class Program
    {
        static void Main(string[] args)
        {
            myWCF.Service1Client client = new TCPWCFClient.myWCF.Service1Client();
            client.ClientCredentials.Windows.ClientCredential.UserName   = "administrator"; //服务主机上的windows登陆名
            client.ClientCredentials.Windows.ClientCredential.Password = "a123";//服务主机上的windows登陆密码
            //client.ClientCredentials.Windows.ClientCredential.Domain = "AD";

            /*如果客户机和服务器机在域中的话,可以把这个交给AD去管理 而不去加用户名密码(请看后面的代码)(有关AD的知识就看相关网管的知识)*/
            /*下面这样写也是可以的*/
            //client.ClientCredentials.UserName.UserName = "administrator"; //服务主机上的windows登陆名
            //client.ClientCredentials.UserName.Password = "a123";//服务主机上的windows登陆密码
            Console.Write(client.GetData("客戶端傳過去的值!"));
            Console.Read();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TCPWCFClient
{
    class Program
    {
        static void Main(string[] args)
        {
            myWCF.Service1Client client = new TCPWCFClient.myWCF.Service1Client();
            //client.ClientCredentials.Windows.ClientCredential.UserName   = "administrator"; //服务主机上的windows登陆名
            //client.ClientCredentials.Windows.ClientCredential.Password = "a123";//服务主机上的windows登陆密码
            /*这样不提供用户名密码才算得上是真正的集成windows身份验证(运行当前客户机的登陆名密码去服务主机上或者AD上验证其有效性) */
            Console.Write(client.GetData("客戶端傳過去的值!"));
            Console.Read();
        }
    }
}

这节讲的主要是用netTcpBinding + 集成验证模式

到此结束,继续看老徐的博客