﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-jinfeng_wang-随笔分类-Other</title><link>http://www.blogjava.net/jinfeng_wang/category/578.html</link><description>G-G-S,D-D-U!</description><language>zh-cn</language><lastBuildDate>Thu, 26 Jul 2007 12:13:14 GMT</lastBuildDate><pubDate>Thu, 26 Jul 2007 12:13:14 GMT</pubDate><ttl>60</ttl><item><title>谈谈基于Kerberos的Windows Network Authentication  zz</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132605.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Thu, 26 Jul 2007 10:02:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132605.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/132605.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/132605.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/132605.html</trackback:ping><description><![CDATA[<a href="http://www.cnblogs.com/artech/archive/2007/07/05/807492.html">http://www.cnblogs.com/artech/archive/2007/07/05/807492.html</a>&nbsp;<br><br><br>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">前几天在给人解释Windows是如何通过Kerberos进行Authentication的时候，讲了半天也别把那位老兄讲明白，还差点把自己给绕进去。后来想想原因有以下两点：对于一个没有完全不了解Kerberos的人来说，Kerberos的整个Authentication过程确实不好理解——一会儿以这个Key进行加密、一会儿又要以另一个Key进行加密，确实很容易把人给弄晕；另一方面是我讲解方式有问题，一开始就从Kerberos的3个Sub-protocol全面讲述整个Authentication 过程，对于一个完全不了解Kerberos的人来说要求也忒高了点。为此，我花了一些时间写了这篇文章，尽量以由浅入深、层层深入的方式讲述我所理解的基于Kerberos的Windows Network Authentication，希望这篇文章能帮助那些对Kerberos不明就里的人带来一丝帮助。对于一些不对的地方，欢迎大家批评指正。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>一、&nbsp;基本原理</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Authentication解决的是&#8220;如何证明某个人确确实实就是他或她所声称的那个人&#8221;的问题。对于如何进行Authentication，我们采用这样的方法：如果一个秘密（secret）仅仅存在于A和B，那么有个人对B声称自己就是A，B通过让A提供这个秘密来证明这个人就是他或她所声称的A。这个过程实际上涉及到3个重要的关于Authentication的方面：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Secret如何表示。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">A如何向B提供Secret。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">B如何识别Secret。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">基于这3个方面，我们把Kerberos Authentication进行最大限度的简化：整个过程涉及到Client和Server，他们之间的这个Secret我们用一个Key（<strong><span style="FONT-SIZE: 12pt">K</span>Server-Client</strong>）来表示。Client为了让Server对自己进行有效的认证，向对方提供如下两组信息：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">代表Client自身Identity的信息，为了简便，它以明文的形式传递。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: verdana" align=left>将Client的Identity使用<strong><span style="FONT-SIZE: 12pt">K</span>Server-Client</strong>作为Public Key、并采用对称加密算法进行加密。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">由于<strong><span style="FONT-SIZE: 12pt">K</span>Server-Client</strong>仅仅被Client和Server知晓，所以被Client使用KServer-Client加密过的Client Identity只能被Client和Server解密。同理，Server接收到Client传送的这两组信息，先通过<span style="FONT-SIZE: 12pt"><strong><span style="FONT-SIZE: 12pt">K</span><font size=2>Server-Client</font></strong></span>对后者进行解密，随后将机密的数据同前者进行比较，如果完全一样，则可以证明Client能过提供正确的<strong><span style="FONT-SIZE: 12pt">K</span>Server-Client</strong>，而这个世界上，仅仅只有真正的Client和自己知道<strong><span style="FONT-SIZE: 12pt">K</span>Server-Client</strong>，所以可以对方就是他所声称的那个人。<br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><img height=269 alt="" src="http://www.cnblogs.com/images/cnblogs_com/artech/kerberos_01_01.jpg" width=576 border=0><br>Keberos大体上就是按照这样的一个原理来进行Authentication的。但是Kerberos远比这个复杂，我将在后续的章节中不断地扩充这个过程，知道Kerberos真实的认证过程。为了使读者更加容易理解后续的部分，在这里我们先给出两个重要的概念：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>Long-term Key/Master Key</strong>：在Security的领域中，有的Key可能长期内保持不变，比如你在密码，可能几年都不曾改变，这样的Key、以及由此派生的Key被称为Long-term Key。对于Long-term Key的使用有这样的原则：被Long-term Key加密的数据不应该在网络上传输。原因很简单，一旦这些被Long-term Key加密的数据包被恶意的网络监听者截获，在原则上，只要有充足的时间，他是可以通过计算获得你用于加密的Long-term Key的——任何加密算法都不可能做到绝对保密。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">在一般情况下，对于一个Account来说，密码往往仅仅限于该Account的所有者知晓，甚至对于任何Domain的Administrator，密码仍然应该是保密的。但是密码却又是证明身份的凭据，所以必须通过基于你密码的派生的信息来证明用户的真实身份，在这种情况下，一般将你的密码进行Hash运算得到一个Hash code, 我们一般管这样的Hash Code叫做Master Key。由于Hash Algorithm是不可逆的，同时保证密码和Master Key是一一对应的，这样既保证了你密码的保密性，有同时保证你的Master Key和密码本身在证明你身份的时候具有相同的效力。</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>Short-term Key/Session Key</strong>：由于被Long-term Key加密的数据包不能用于网络传送，所以我们使用另一种Short-term Key来加密需要进行网络传输的数据。由于这种Key只在一段时间内有效，即使被加密的数据包被黑客截获，等他把Key计算出来的时候，这个Key早就已经过期了。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>二、引入Key Distribution: <span style="FONT-SIZE: 12pt">K</span>Server-Client从何而来</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">上面我们讨论了Kerberos Authentication的基本原理：通过让被认证的一方提供一个仅限于他和认证方知晓的Key来鉴定对方的真实身份。而被这个Key加密的数据包需要在Client和Server之间传送，所以这个Key不能是一个<strong>Long-term Key</strong>，而只可能是<strong>Short-term Key</strong>，这个可以仅仅在Client和Server的一个Session中有效，所以我们称这个Key为Client和Server之间的Session Key（<strong><span style="FONT-SIZE: 12pt">S</span>Server-Client</strong>）。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">现在我们来讨论Client和Server如何得到这个<strong><span style="FONT-SIZE: 12pt">S</span>Server-Client</strong>。在这里我们要引入一个重要的角色：<strong>Kerberos Distribution Center-KDC</strong>。KDC在整个Kerberos Authentication中作为Client和Server共同信任的第三方起着重要的作用，而Kerberos的认证过程就是通过这3方协作完成。顺便说一下，Kerberos起源于希腊神话，是一支守护着冥界长着3个头颅的神犬，在keberos Authentication中，Kerberos的3个头颅代表中认证过程中涉及的3方：<strong>Client、Server和KDC</strong>。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">对于一个Windows Domain来说，<strong>Domain Controller</strong>扮演着KDC的角色。KDC维护着一个存储着该Domain中所有帐户的<strong>Account Database</strong>（一般地，这个Account Database由<strong>AD</strong>来维护），也就是说，他知道属于每个Account的名称和派生于该Account Password的<strong>Master Key</strong>。而用于Client和Server相互认证的<strong><span style="FONT-SIZE: 12pt">S</span>Server-Client</strong>就是有KDC分发。下面我们来看看KDC分发<strong><span style="FONT-SIZE: 12pt">S</span>Server-Client</strong>的过程。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">通过下图我们可以看到KDC分发SServer-Client的简单的过程：首先Client向KDC发送一个对SServer-Client的申请。这个申请的内容可以简单概括为&#8220;<strong>我是某个Client，我需要一个Session Key用于访问某个Server</strong> &#8221;。KDC在接收到这个请求的时候，生成一个Session Key，为了保证这个Session Key仅仅限于发送请求的Client和他希望访问的Server知晓，KDC会为这个Session Key生成两个Copy，分别被Client和Server使用。然后从Account database中提取Client和Server的Master Key分别对这两个Copy进行对称加密。对于后者，和Session Key一起被加密的还包含关于Client的一些信息。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">KDC现在有了两个分别被Client和Server 的Master Key加密过的Session Key，这两个Session Key如何分别被Client和Server获得呢？也许你 马上会说，KDC直接将这两个加密过的包发送给Client和Server不就可以了吗，但是如果这样做，对于Server来说会出现下面 两个问题：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">由于一个Server会面对若干不同的Client, 而每个Client都具有一个不同的Session Key。那么Server就会为所有的Client维护这样一个Session Key的列表，这样做对于Server来说是比较麻烦而低效的。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">由于网络传输的不确定性，可能出现这样一种情况：Client很快获得Session Key，并将这个Session Key作为Credential随同访问请求发送到Server，但是用于Server的Session Key确还没有收到，并且很有可能承载这个Session Key的永远也到不了Server端，Client将永远得不到认证。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">为了解决这个问题，Kerberos的做法很简单，将这两个被加密的Copy一并发送给Client，属于Server的那份由Client发送给Server。<br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><img height=277 alt="" src="http://www.cnblogs.com/images/cnblogs_com/artech/kerberos_01_02.jpg" width=582 border=0><br>可能有人会问，KDC并没有真正去认证这个发送请求的Client是否真的就是那个他所声称的那个人，就把Session Key发送给他，会不会有什么问题？如果另一个人（比如Client B）声称自己是Client A，他同样会得到Client A和Server的Session Key，这会不会有什么问题？实际上不存在问题，因为Client B声称自己是Client A，KDC就会使用Client A的Password派生的Master Key对Session Key进行加密，所以真正知道Client A 的Password的一方才会通过解密获得Session Key。&nbsp;</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>三、引入Authenticator - <span lang=ZH-CN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: simsun">为有效的证明自己提供证据</span></strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">通过上面的过程，Client实际上获得了两组信息：一个通过自己Master Key加密的Session Key，另一个被Sever的Master Key加密的数据包，包含Session Key和关于自己的一些确认信息。通过第一节，我们说只要通过一个双方知晓的Key就可以对对方进行有效的认证，但是在一个网络的环境中，这种简单的做法是具有安全漏洞，为此,Client需要提供更多的证明信息，我们把这种证明信息称为<strong>Authenticator</strong>，在Kerberos的Authenticator实际上就是<strong>关于Client的一些信息</strong>和当前时间的一个<strong>Timestamp</strong>（关于这个安全漏洞和Timestamp的作用，我将在后面解释）。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">在这个基础上，我们再来看看Server如何对Client进行认证：Client通过<strong>自己的Master Key</strong>对KDC加密的Session Key进行解密从而获得<strong>Session Key</strong>，随后创建<strong>Authenticator（Client Info + Timestamp）</strong>并用<strong>Session Key</strong>对其加密。最后连同从KDC获得的、被<strong>Server的Master Key</strong>加密过的数据包（Client <strong>Info + Session Key</strong>）一并发送到Server端。我们把通过Server的Master Key加密过的数据包称为<strong>Session Ticket</strong>。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">当Server接收到这两组数据后，先使用他<strong>自己的Master Key</strong>对Session Ticket进行解密，从而获得<strong>Session Key</strong>。随后使用该<strong>Session Key</strong>解密<strong>Authenticator</strong>，通过比较<strong>Authenticator中的Client Info</strong>和<strong>Session Ticket中的Client Info</strong>从而实现对Client的认证。<br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong><img height=277 alt="" src="http://www.cnblogs.com/images/cnblogs_com/artech/kerberos_01_03.jpg" width=582 border=0><br>为什么要使用Timestamp？</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">到这里，很多人可能认为这样的认证过程天衣无缝：只有当Client提供正确的Session Key方能得到Server的认证。但是在现实环境中，这存在很大的安全漏洞。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">我们试想这样的现象：Client向Server发送的数据包被某个恶意网络监听者截获，该监听者随后将数据包座位自己的Credential冒充该Client对Server进行访问，在这种情况下，依然可以很顺利地获得Server的成功认证。为了解决这个问题，Client在<strong>Authenticator</strong>中会加入一个当前时间的<strong>Timestamp</strong>。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">在Server对Authenticator中的Client Info和Session Ticket中的Client Info进行比较之前，会先提取Authenticator中的<strong>Timestamp</strong>，并同<strong>当前的时间</strong>进行比较，如果他们之间的偏差超出一个可以<strong>接受的时间范围（一般是5mins），</strong>Server会直接拒绝该Client的请求。在这里需要知道的是，Server维护着一个列表，这个列表记录着在这个可接受的时间范围内所有进行认证的Client和认证的时间。对于时间偏差在这个可接受的范围中的Client，Server会从这个这个列表中获得<strong>最近一个该Client的认证时间</strong>，只有当<strong>Authenticator中的Timestamp晚于通过一个Client的最近的认证时间</strong>的情况下，Server采用进行后续的认证流程。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>Time Synchronization的重要性</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">上述 基于Timestamp的认证机制只有在Client和Server端的时间保持同步的情况才有意义。所以保持Time Synchronization在整个认证过程中显得尤为重要。在一个Domain中，一般通过访问同一个<strong>Time Service</strong>获得当前时间的方式来实现时间的同步。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>双向认证（Mutual Authentication）</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Kerberos一个重要的优势在于它能够提供双向认证：<strong>不但Server可以对Client 进行认证，Client也能对Server进行认证</strong>。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">具体过程是这样的，如果Client需要对他访问的Server进行认证，会在它向Server发送的Credential中设置一个是否需要认证的Flag。Server在对Client认证成功之后，会把Authenticator中的Timestamp提出出来，通过Session Key进行加密，当Client接收到并使用Session Key进行解密之后，如果确认<strong>Timestamp</strong>和原来的完全一致，那么他可以认定Server正式他试图访问的Server。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">那么为什么Server不直接把通过Session Key进行加密的Authenticator原样发送给Client，而要把Timestamp提取出来加密发送给Client呢？原因在于防止恶意的监听者通过获取的Client发送的Authenticator冒充Server获得Client的认证。<br><br><br><span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>四、引入Ticket Granting &nbsp;Service</strong></span><br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">通过上面的介绍，我们发现Kerberos实际上一个基于<strong>Ticket</strong>的认证方式。Client想要获取Server端的资源，先得通过Server的认证；而认证的先决条件是Client向Server提供从KDC获得的一个有<strong>Server的Master Key</strong>进行加密的<strong>Session Ticket（Session Key + Client Info）</strong>。可以这么说，Session Ticket是Client进入Server领域的一张门票。而这张门票必须从一个合法的Ticket颁发机构获得，这个颁发机构就是<strong>Client和Server双方信任的KDC</strong>， 同时这张Ticket具有超强的防伪标识：它是被Server的Master Key加密的。对Client来说， 获得Session Ticket是整个认证过程中最为关键的部分。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">上面我们只是简单地从大体上说明了KDC向Client分发Ticket的过程，而真正在Kerberos中的Ticket Distribution要复杂一些。为了更好的说明整个Ticket Distribution的过程，我在这里做一个类比。现在的股事很火爆，上海基本上是全民炒股，我就举一个认股权证的例子。有的上市公司在股票配股、增发、基金扩募、股份减持等情况会向公众发行<strong>认股权证</strong>，认股权证的持有人可以凭借这个权证认购一定数量的该公司股票，认股权证是一种具有看涨期权的金融衍生产品。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">而我们今天所讲的Client获得Ticket的过程也和通过认股权证购买股票的过程类似。如果我们把Client提供给Server进行认证的Ticket比作股票的话，那么Client在从KDC那边获得Ticket之前，需要先获得这个Ticket的认购权证，这个认购权证在Kerberos中被称为<strong>TGT：Ticket Granting Ticket</strong>，TGT的分发方仍然是KDC。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">我们现在来看看Client是如何从KDC处获得TGT的：首先Client向KDC发起对TGT的申请，申请的内容大致可以这样表示：&#8220;<strong>我需要一张TGT用以申请获取用以访问所有Server的Ticket</strong>&#8221;。KDC在收到该申请请求后，生成一个用于该Client和KDC进行安全通信的<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>。为了保证该Session Key仅供该Client和自己使用，KDC使用<strong>Client的Master Key</strong>和<strong>自己的Master Key</strong>对生成的Session Key进行加密，从而获得两个加密的<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Client</strong>的Copy。对于后者，随<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Client</strong>一起被加密的还包含以后用于鉴定Client身份的关于Client的一些信息。最后KDC将这两份Copy一并发送给Client。这里有一点需要注意的是：为了免去KDC对于基于不同Client的Session Key进行维护的麻烦，就像Server不会保存<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>Server-Client）</strong>一样，KDC也不会去保存这个Session Key（<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Client</strong>），而选择完全靠Client自己提供的方式。<br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><img height=265 alt="" src="http://www.cnblogs.com/images/cnblogs_com/artech/kerberos_01_07.gif" width=572 border=0><br>当Client收到KDC的两个加密数据包之后，先使用<strong>自己的Master Key</strong>对第一个Copy进行解密，从而获得KDC和Client的<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>，并把该Session 和TGT进行缓存。有了Session Key和TGT，Client自己的Master Key将不再需要，因为此后Client可以使用<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Client</strong>向KDC申请用以访问每个Server的Ticket，相对于Client的Master Key这个Long-term Key，SKDC-Client是一个Short-term Key，安全保证得到更好的保障，这也是Kerberos多了这一步的关键所在。同时需要注意的是SKDC-Client是一个Session Key，他具有自己的生命周期，同时TGT和Session相互关联，当Session Key过期，TGT也就宣告失效，此后Client不得不重新向KDC申请新的TGT，KDC将会生成一个不同Session Key和与之关联的TGT。同时，由于Client Log off也导致SKDC-Client的失效，所以SKDC-Client又被称为<strong>Logon Session Key</strong>。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">接下来，我们看看Client如何使用TGT来从KDC获得基于某个Server的Ticket。在这里我要强调一下，Ticket是基于某个具体的Server的，而TGT则是和具体的Server无关的，Client可以使用一个TGT从KDC获得基于不同Server的Ticket。我们言归正传，Client在获得自己和KDC的<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>之后，生成自己的Authenticator以及所要访问的Server名称的并使用<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Client</strong>进行加密。随后连同TGT一并发送给KDC。KDC使用<strong>自己的Master Key</strong>对TGT进行解密，提取Client Info和<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>，然后使用这个<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Client</strong>解密Authenticator获得Client Info，对两个Client Info进行比较进而验证对方的真实身份。验证成功，生成一份基于Client所要访问的Server的Ticket给Client，这个过程就是我们第二节中介绍的一样了。&nbsp;<br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong><img height=265 alt="" src="http://www.cnblogs.com/images/cnblogs_com/artech/kerberos_01_05.gif" width=572 border=0><br>五、Kerberos的3个Sub-protocol：整个Authentication</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">通过以上的介绍，我们基本上了解了整个Kerberos authentication的整个流程：整个流程大体上包含以下3个子过程：</p>
<ol>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client向KDC申请TGT（Ticket Granting Ticket）。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client通过获得TGT向DKC申请用于访问Server的Ticket。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client最终向为了Server对自己的认证向其提交Ticket。</div>
    </li>
</ol>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">不过上面的介绍离真正的Kerberos Authentication还是有一点出入。Kerberos整个认证过程通过3个sub-protocol来完成。这个3个Sub-Protocol分别完成上面列出的3个子过程。这3个sub-protocol分别为：</p>
<ol>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Authentication Service Exchange</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Ticket Granting&nbsp;Service Exchange</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client/Server Exchange</div>
    </li>
</ol>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">下图简单展示了完成这个3个Sub-protocol所进行Message Exchange。<br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong><img height=265 alt="" src="http://www.cnblogs.com/images/cnblogs_com/artech/kerberos_01_06.gif" width=572 border=0><br>1． Authentication Service Exchange</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">通过这个Sub-protocol，KDC（确切地说是KDC中的Authentication Service）实现对Client身份的确认，并颁发给该Client一个TGT。具体过程如下：</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client向KDC的Authentication Service发送Authentication Service Request（<strong>KRB_AS_REQ</strong>）, 为了确保KRB_AS_REQ仅限于自己和KDC知道，Client使用自己的Master Key对KRB_AS_REQ的主体部分进行加密（KDC可以通过Domain 的Account Database获得该Client的Master Key）。KRB_AS_REQ的大体包含以下的内容：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Pre-authentication data：包含用以证明自己身份的信息。说白了，就是证明自己知道自己声称的那个account的Password。一般地，它的内容是一个被Client的Master key加密过的Timestamp。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client name &amp; realm: 简单地说就是Domain name\Client</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Server Name：注意这里的Server Name并不是Client真正要访问的Server的名称，而我们也说了TGT是和Server无关的（Client只能使用Ticket，而不是TGT去访问Server）。这里的Server Name实际上是<strong>KDC的Ticket Granting Service的Server Name</strong>。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">AS（Authentication Service）通过它接收到的KRB_AS_REQ验证发送方的是否是在Client name &amp; realm中声称的那个人，也就是说要验证发送放是否知道Client的Password。所以AS只需从Account Database中提取Client对应的Master Key对Pre-authentication data进行解密，如果是一个合法的Timestamp，则可以证明发送放提供的是正确无误的密码。验证通过之后，AS将一份Authentication Service Response（KRB_AS_REP）发送给Client。KRB_AS_REQ主要包含两个部分：本Client的Master Key加密过的Session Key（SKDC-Client：Logon Session Key）和被自己（KDC）加密的TGT。而TGT大体又包含以下的内容：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Session Key: SKDC-Client：Logon Session Key</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client name &amp; realm: 简单地说就是Domain name\Client</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">End time: TGT到期的时间。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client通过自己的Master Key对第一部分解密获得Session Key（SKDC-Client：Logon Session Key）之后，携带着TGT便可以进入下一步：TGS（Ticket Granting Service）Exchange。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>2． TGS（Ticket Granting Service）Exchange</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">TGS（Ticket Granting Service）Exchange通过Client向KDC中的TGS（Ticket Granting Service）发送Ticket Granting Service Request（<strong>KRB_TGS_REQ</strong>）开始。KRB_TGS_REQ大体包含以下的内容：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">TGT：Client通过AS Exchange获得的Ticket Granting Ticket，TGT被KDC的Master Key进行加密。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Authenticator：用以证明当初TGT的拥有者是否就是自己，所以它必须以TGT的办法方和自己的Session Key（SKDC-Client：Logon Session Key）来进行加密。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client name &amp; realm: 简单地说就是Domain name\Client。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Server name &amp; realm: 简单地说就是Domain name\Server，这回是Client试图访问的那个Server。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">TGS收到KRB_TGS_REQ在发给Client真正的Ticket之前，先得整个Client提供的那个TGT是否是AS颁发给它的。于是它不得不通过Client提供的Authenticator来证明。但是Authentication是通过<strong>Logon Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>进行加密的，而自己并没有保存这个Session Key。所以TGS先得通过自己的Master Key对Client提供的TGT进行解密，从而获得这个Logon Session Key（SKDC-Client），再通过这个<strong>Logon Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>解密Authenticator进行验证。验证通过向对方发送Ticket Granting Service Response（KRB_TGS_REP）。这个KRB_TGS_REP有两部分组成：使用<strong>Logon Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>加密过用于Client和Server的<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>Server-Client）</strong>和使用<strong>Server的Master Key</strong>进行加密的Ticket。该Ticket大体包含以下一些内容：</p>
<ul>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Session Key：SServer-Client。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client name &amp; realm: 简单地说就是Domain name\Client。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">End time: Ticket的到期时间。</div>
    </li>
</ul>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Client收到KRB_TGS_REP，使用<strong>Logon Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Client）</strong>解密第一部分后获得<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>Server-Client）</strong>。有了Session Key和Ticket，Client就可以之间和Server进行交互，而无须在通过KDC作中间人了。所以我们说Kerberos是一种高效的认证方式，它可以直接通过Client和Server双方来完成，不像Windows NT 4下的NTLM认证方式，每次认证都要通过一个双方信任的第3方来完成。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">我们现在来看看 Client如果使用Ticket和Server怎样进行交互的，这个阶段通过我们的第3个Sub-protocol来完成：<strong>CS（Client/Server ）Exchange</strong>。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>3． CS（Client/Server ）Exchange</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">这个已经在本文的第二节中已经介绍过，对于重复发内容就不再累赘了。Client通过TGS Exchange获得Client和Server的<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>Server-Client）</strong>，随后创建用于证明自己就是Ticket的真正所有者的Authenticator，并使用<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>Server-Client）</strong>进行加密。最后将这个被加密过的Authenticator和Ticket作为Application Service Request（KRB_AP_REQ）发送给Server。除了上述两项内容之外，KRB_AP_REQ还包含一个Flag用于表示Client是否需要进行双向验证（Mutual Authentication）。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Server接收到KRB_AP_REQ之后，通过自己的Master Key解密Ticket，从而获得Session Key（SServer-Client）。通过Session Key（SServer-Client）解密Authenticator，进而验证对方的身份。验证成功，让Client访问需要访问的资源，否则直接拒绝对方的请求。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">对于需要进行双向验证，Server从Authenticator提取Timestamp，使用Session Key（SServer-Client）进行加密，并将其发送给Client用于Client验证Server的身份。<br><br><br><strong>六、User2User Sub-Protocol：有效地保障Server的安全</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">通过3个Sub-protocol的介绍，我们可以全面地掌握整个Kerberos的认证过程。实际上，在Windows 2000时代，基于Kerberos的Windows Authentication就是按照这样的工作流程来进行的。但是我在上面一节结束的时候也说了，基于3个Sub-protocol的Kerberos作为一种Network Authentication是具有它自己的局限和安全隐患的。我在整篇文章一直在强调这样的一个原则：<strong>以某个Entity的Long-term Key加密的数据不应该在网络中传递</strong>。原因很简单，所有的加密算法都不能保证100%的安全，对加密的数据进行解密只是一个时间的过程，最大限度地提供安全保障的做法就是：<strong>使用一个Short-term key（Session Key）代替Long-term Key对数据进行加密，使得恶意用户对其解密获得加密的Key时，该Key早已失效</strong>。但是对于3个Sub-Protocol的C/S Exchange，Client携带的Ticket却是被<strong>Server Master Key</strong>进行加密的，这显现不符合我们提出的原则，降低Server的安全系数。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">所以我们必须寻求一种解决方案来解决上面的问题。这个解决方案很明显：就是采用一个Short-term的Session Key，而不是Server Master Key对Ticket进行加密。这就是我们今天要介绍的Kerberos的第4个Sub-protocol：<strong>User2User Protocol</strong>。我们知道，既然是Session Key，仅必然涉及到两方，而在Kerberos整个认证过程涉及到3方：Client、Server和KDC，所以用于加密Ticket的只可能是Server和KDC之间的<strong>Session Key（<span style="FONT-SIZE: 12pt">S</span>KDC-Server）。</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">我们知道Client通过在AS Exchange阶段获得的TGT从KDC那么获得访问Server的Ticket。原来的Ticket是通过<strong>Server的Master Key</strong>进行加密的，而这个Master Key可以通过Account Database获得。但是现在KDC需要使用Server和KDC之间的<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Server</strong>进行加密，而KDC是不会维护这个Session Key，所以<strong>这个Session Key只能靠申请Ticket的Client提供</strong>。所以在AS Exchange和TGS Exchange之间，Client还得对Server进行请求已获得Server和KDC之间的Session Key（<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Server</strong>）。而对于Server来说，它可以像Client一样通过<strong>AS Exchange</strong>获得他和KDC之间的Session Key（<strong><span style="FONT-SIZE: 12pt">S</span>KDC-Server</strong>）和一个封装了这个Session Key并被<strong>KDC的Master Key进行加密的TGT</strong>，一旦获得这个TGT，Server会缓存它，以待Client对它的请求。我们现在来详细地讨论这一过程。<br></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><img height=265 alt="" src="http://www.cnblogs.com/images/cnblogs_com/artech/kerberos_03_01.gif" width=572 border=0><br>上图基本上翻译了基于User2User的认证过程，这个过程由4个步骤组成。我们发现较之我在上面一节介绍的基于传统3个Sub-protocol的认证过程，这次对了第2部。我们从头到尾简单地过一遍：</p>
<ol>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">AS Exchange：Client通过此过程获得了属于自己的TGT，有了此TGT，Client可凭此向KDC申请用于访问某个Server的Ticket。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">这一步的主要任务是获得封装了Server和KDC的Session Key（SKDC-Server）的属于Server的TGT。如果该TGT存在于Server的缓存中，则Server会直接将其返回给Client。否则通过AS Exchange从KDC获取。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">TGS Exchange：Client通过向KDC提供自己的TGT，Server的TGT以及Authenticator向KDC申请用于访问Server的Ticket。KDC使用先用自己的Master Key解密Client的TGT获得SKDC-Client，通过SKDC-Client解密Authenticator验证发送者是否是TGT的真正拥有者，验证通过再用自己的Master Key解密Server的TGT获得KDC和Server 的Session Key（SKDC-Server），并用该Session Key加密Ticket返回给Client。</div>
    <li>
    <div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">C/S Exchange：Client携带者通过KDC和Server 的Session Key（SKDC-Server）进行加密的Ticket和通过Client和Server的Session Key（SServer-Client）的Authenticator访问Server，Server通过SKDC-Server解密Ticket获得SServer-Client，通过SServer-Client解密Authenticator实现对Client的验证。</div>
    </li>
</ol>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">这就是整个过程。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>七、Kerberos的优点</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">分析整个Kerberos的认证过程之后，我们来总结一下Kerberos都有哪些优点：</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>1．较高的Performance</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">虽然我们一再地说Kerberos是一个涉及到3方的认证过程：Client、Server、KDC。但是一旦Client获得用过访问某个Server的Ticket，该Server就能根据这个Ticket实现对Client的验证，而无须KDC的再次参与。和传统的基于Windows NT 4.0的每个完全依赖Trusted Third Party的NTLM比较，具有较大的性能提升。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>2．实现了双向验证（Mutual Authentication）</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">传统的NTLM认证基于这样一个前提：Client访问的远程的Service是可信的、无需对于进行验证，所以NTLM不曾提供双向验证的功能。这显然有点理想主义，为此Kerberos弥补了这个不足：Client在访问Server的资源之前，可以要求对Server的身份执行认证。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>3．对Delegation的支持</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Impersonation和Delegation是一个分布式环境中两个重要的功能。Impersonation允许Server在本地使用Logon 的Account执行某些操作，Delegation需用Server将logon的Account带入到另过一个Context执行相应的操作。NTLM仅对Impersonation提供支持，而Kerberos通过一种双向的、可传递的（Mutual 、Transitive）信任模式实现了对Delegation的支持。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><strong>4．互操作性（Interoperability）</strong></p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">Kerberos最初由MIT首创，现在已经成为一行被广泛接受的标准。所以对于不同的平台可以进行广泛的互操作。<br></p>
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/132605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-07-26 18:02 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP.NET应用程序的安全方案(身份验证)  zz</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132603.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Thu, 26 Jul 2007 09:59:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132603.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/132603.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/132603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/132603.html</trackback:ping><description><![CDATA[<div id=archivers>ASP.NET应用程序的安全方案(身份验证)
<p>&#160;</p>
<p>摘要：本文ASP.NET应用程序身份验证的概念，介绍了各种身份验证模式并进行了比较，阐述了选择身份验证模式的机制，并给出了一种基于窗体身份验证模式的实现方法。</p>
<p>关键字：身份验证&nbsp;authentication&nbsp;ASP.NET&nbsp;WEB应用</p>
<p>1.身份验证概念&nbsp;任何成功的应用程序安全策略的基础都是稳固的身份验证和授权手段，以及提供机密数据的保密性和完整性的安全通讯。<br>身份验证（authentication）是一个标识应用程序客户端的过程，这里的客户端可能包括终端用户、服务、进程或计算机，通过了身份验证的客户端被称为主体（principal）。身份验证可以跨越应用程序的多个层发生。终端用户起初由Web应用程序进行身份验证，通常根据用户名和密码进行；随后终端用户的请求由中间层应用程序服务器和数据库服务器进行处理，这过程中也将进行身份验证以便验证并处理这些请求。<br>图1列出了各种安全技术以及每种技术所提供的主要验证方式。<br>2.&nbsp;身份验证模式&nbsp;如图1所示，Windows&nbsp;2000上的.NET框架上提供了以下几种身份验证：<br>ASP.NET身份验证模式&nbsp;Enterprise&nbsp;Services身份验证&nbsp;SQL&nbsp;Server身份验证&nbsp;2.1&nbsp;ASP.NET身份验证模式&nbsp;ASP.NET身份验证模式包括Windows、Forms（窗体）、Passport（护照）和None（无）。<br>2.1.1&nbsp;Windows身份验证&nbsp;使用这种身份验证模式时，ASP.NET依赖于IIS对用户进行验证，并创建一个Windows访问令牌来表示已通过验证的标识。IIS提供以下几种身份验证机制：<br>基本身份验证简要身份验证集成Windows身份验证证书身份验证匿名身份验证&nbsp;2.1.2&nbsp;护照身份验证&nbsp;使用这种身份验证模式时，ASP.NET使用Microsoft&nbsp;Passport的集中式身份验证服务，ASP.NET为Microsoft&nbsp;Passport软件开发包（SDK）所提供的功能提供了一个方便的包装（Wrapper）。此SDK必须安装在WEB服务器上。<br>2.1.3&nbsp;窗体身份验证&nbsp;这种验证方式使用客户端重定向功能，将未通过身份验证的用户转发到特定的登录窗体，要求用户输入其凭据信息（通常是用户名和密码）。这些凭据信息被验证后，系统生成一个身份验证票证（ticket）并将其返回客户端。身份验证票证可在用户的会话期间维护用户的身份标识信息，以及用户所属的角色列表（可选）。<br>2.1.4&nbsp;None&nbsp;使用这种身份验证模式，表示你不希望对用户进行验证，或是采用自定义的身份验证协议。<br>2.2&nbsp;Enterprise&nbsp;Services身份验证&nbsp;Enterprise&nbsp;Services身份验证通过使用底层的远程过程调用（RPC，Remote&nbsp;Procedure&nbsp;Call）传输结构来进行，而这种结构又使用了操作系统安全服务提供程序接口（SSPI，Security&nbsp;Service&nbsp;Provider&nbsp;Interface）。可以利用Kerberose或NTLM身份验证机制对Enterprise&nbsp;Services应用程序的客户端进行验证。<br>2.3&nbsp;SQL&nbsp;Server身份验证&nbsp;SQL&nbsp;Server可以通过Windows身份验证机制（Kerberose或NTLM），也可以通过其内置的身份验证方案-SQL身份验证机制进行验证。通常有两种可用的验证方案。<br>2.3.1&nbsp;SQL&nbsp;Server&nbsp;and&nbsp;Windows&nbsp;客户端可用通过SQL&nbsp;Server身份验证或Windows身份验证机制来连接SQL&nbsp;Server的某个实例。这种方式有时也被称为混合模式的身份验证。<br>2.3.2&nbsp;Windows&nbsp;Only&nbsp;客户端必须通过使用Windows身份验证机制来连接到SQL&nbsp;Server的一个实例。<br>3.&nbsp;选择身份验证机制&nbsp;设计分布式应用程序的身份验证是一项具有挑战性的任务。在应用程序开发的早期阶段，进行适当的身份验证设计有助于降低许多安全风险。&nbsp;3.1&nbsp;各种身份验证机制的比较&nbsp;用户是否需要在服务器域中拥有Windows帐户是否支持委托是否需要Windows&nbsp;2000客户端和服务器凭据是否明文传输（需要SSL）是否支持非IE浏览器&nbsp;基本身份验证&nbsp;是&nbsp;是&nbsp;否&nbsp;是&nbsp;是&nbsp;简要身份验证&nbsp;是&nbsp;否&nbsp;是&nbsp;否&nbsp;否&nbsp;NTLM身份验证&nbsp;是&nbsp;否&nbsp;否&nbsp;否&nbsp;否&nbsp;Kerberos身份验证&nbsp;是&nbsp;是&nbsp;是&nbsp;否&nbsp;否&nbsp;证书身份验证&nbsp;否&nbsp;是&nbsp;否&nbsp;否&nbsp;是&nbsp;窗体身份验证&nbsp;否&nbsp;是&nbsp;否&nbsp;是&nbsp;是&nbsp;护照身份验证&nbsp;否&nbsp;是&nbsp;否&nbsp;否&nbsp;是&nbsp;3.2&nbsp;选择身份验证机制需要考虑的因素&nbsp;标识&nbsp;只有当应用程序的用户具有的Windows帐户可以通过一个受信任的权威机构（它可以被应用程序Web服务器访问）来进行验证时，使用Windows身份验证机制才是合适的。<br>凭据管理&nbsp;Windows身份验证的一个关键优势在于它可以使用操作系统进行凭据管理。当使用非Windows身份验证方式，例如窗体身份验证时，必须仔细考虑在何处以及如何保存用户凭据。其中最常用的方式是使用SQL&nbsp;Server数据库或是使用位于Active&nbsp;Directory中的User对象。<br>标识流动&nbsp;是否需要实现一个模拟/委托模型，并将原始调用者的安全上下文在操作系统级进行跨层流动-例如，以便支持审核或针对每个用户的精细授权。<br>浏览器类型&nbsp;应用程序的所有用户是否都拥有IE浏览器？或是你是否需要支持一个具有混合型浏览器的用户群？&nbsp;我们选择身份验证时需要根据各种方式的特点，综合考虑以上因素。<br></p>
&nbsp;</div>
<div id=archivers>3.3&nbsp;Intranet系统的选择决策流程&nbsp;参见图2。<br>3.4&nbsp;SQL&nbsp;Server用户验证&nbsp;对SQL&nbsp;Server的客户端进行验证，一般说来Windows身份验证要比SQL&nbsp;Server身份验证更安全，原因主要有以下几点：&nbsp;前者负责管理用户的凭据信息，而且用户的凭据不会在网络上传输。可以避免在连接字符串中嵌入用户名和密码。可通过密码过期时限、最小密码长度、以及多次无效登录后请求的帐户锁定等措施改进登录安全性。这样可以见少词典攻击的威胁。&nbsp;但是某些特定的应用程序方案中不允许使用Windows身份验证，例如：&nbsp;数据库客户端和数据库服务器由一个防火墙分隔开，从而导致无法使用Windows身份验证。应用程序需要使用多个标识连接到一个或多个数据库。连接到的数据库不是SQL&nbsp;Server。在ASP.NET中没有一种安全的方式以特定的Windows用户的身份运行代码。&nbsp;在以上这些方案中，将必须使用SQL身份验证，或是数据库的本机身份验证机制。&nbsp;<br>4.&nbsp;ASP.NET身份验证实现&nbsp;4.1&nbsp;方案特性在这部分，仅提供了一种Intranet下交互式WEB应用程序的身份验证的实现，本方案假设具有以下特性：&nbsp;只有通过了身份验证的客户端才能访问应用程序。数据库相信应用程序对用户进行了相应的身份验证-即应用程序代表用户对数据库进行调用。&nbsp;WEB应用程序通过使用ASP.NET进程帐户连接到数据库。用户的凭据信息是根据SQL&nbsp;Server数据库进行验证的。使用窗体身份验证模式。&nbsp;在WEB应用程序中，用户的凭据信息是根据SQL&nbsp;Server数据库，采用窗体身份验证模式，便于实现用户个性化设计。采用应用程序代表用户对数据库进行调用的方式，可采用受信任子系统模型，更好地利用数据库连接池，并且可以保证用户不能直接访问后端数据库，另外可以减少后端的ACL管理工作。<br>4.2&nbsp;安全配置步骤&nbsp;4.2.1&nbsp;IIS配置步骤&nbsp;对Web服务的虚拟根目录启用匿名访问。<br>主要方法是使用IIS&nbsp;MMC管理单元，右击应用程序的虚拟目录，然后单击属性---〉目录安全性--〉匿名访问和安全控制--〉编辑。<br>4.2.2&nbsp;ASP.NET配置步骤&nbsp;1．&nbsp;将ASPNET帐户（用于运行ASP.NET）的密码重新设置为一个更安全的密码。<br>这样允许在数据库服务器上复制一个本地帐户（具有相同的用户名和密码）。为了使用Windows身份验证连接到数据库时，能够使ASPNET帐户对来自数据库的网络身份验证要求进行响应，这是必须的。<br>具体方法是编辑位于%windr%\Microsoft.NET\Framework\v1.1.4322\CONFIG目录下的&nbsp;Machine.config文件，将&lt;processModel&gt;元素上的密码属性重新配置，将其默认值&lt;!-UserName=&nbsp;"machine"&nbsp;password="AutoGenerate"&nbsp;--&gt;改为&lt;!-UserName="machine"&nbsp;password="NewPassword"&nbsp;--&gt;。<br>2．&nbsp;配置ASP.NET，使用窗体身份验证。<br>编辑位于WEB服务的虚拟根目录下的Web.config文件，将&lt;authentication&gt;元素设置为：<br>&lt;authentication&nbsp;mode="Forms"&nbsp;&gt;<br>&lt;forms&nbsp;name="MyAppFormAuth"&nbsp;loginUrl="login.aspx"&nbsp;protection="All"&nbsp;timeout="20"&nbsp;path="/"&gt;<br>&lt;/forms&gt;<br>&lt;/authentication&gt;<br>4.2.3&nbsp;配置SQL&nbsp;Server&nbsp;1．&nbsp;在SQL&nbsp;Server数据库上创建一个和ASP.NET进程帐户匹配的Windows帐户。<br>用户名和密码必须和ASP.NET应用程序帐号匹配。<br>2．&nbsp;配置SQL&nbsp;Server，使其使用Windows身份验证。<br>3．&nbsp;为自定义的ASP.NET应用程序帐户创建一个SQL&nbsp;Server登录，授予对SQL&nbsp;Server的访问权。<br>4．&nbsp;创建一个新的数据库用户，并将登录名映射为数据库用户。<br>5．&nbsp;创建一个用户定义的新数据库角色，并将数据库用户添加到该角色。<br>6．&nbsp;为数据库角色确定数据库权限。&nbsp;<br>4.3&nbsp;程序代码&nbsp;4.3.1&nbsp;身份验证事件序列&nbsp;当未通过身份验证的用户试图放一个受保护的文件或资源被拒绝时，触发的事件序列如图3所示。<br>4.3.2&nbsp;代码实现步骤&nbsp;1．&nbsp;建一个WEB登录窗体并验证用户提供的凭据信息<br>根据SQL&nbsp;Server数据库来验证凭据信息。<br>2．&nbsp;从数据库里获取角色列表<br>3．&nbsp;创建窗体身份验证票证<br>在票证中保存所获取的角色信息。示例代码如下：<br>private&nbsp;void&nbsp;btnLogin_Click(object&nbsp;sender,&nbsp;System.EventArgs&nbsp;e)<br>{<br>//根据SQL&nbsp;Server数据库进行验证（具体实现略）。<br>bool&nbsp;isAuthenticated&nbsp;=&nbsp;IsAuthenticated(&nbsp;txtUserName.Text,&nbsp;txtPassword.Text&nbsp;);<br>if&nbsp;(isAuthenticated&nbsp;==&nbsp;true&nbsp;)<br>{<br>//获取用户的角色<br>string&nbsp;roles&nbsp;=&nbsp;GetRoles(&nbsp;txtUserName.Text,&nbsp;txtPassword.Text&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;创建身份验证票证<br>FormsAuthenticationTicket&nbsp;authTicket&nbsp;=&nbsp;new&nbsp;<br>FormsAuthenticationTicket(1,&nbsp;//&nbsp;version<br>txtUserName.Text,&nbsp;//&nbsp;user&nbsp;name<br>DateTime.Now,&nbsp;//&nbsp;creation<br>DateTime.Now.AddMinutes(60),//&nbsp;Expiration<br>false,&nbsp;//&nbsp;Persistent<br>roles&nbsp;);&nbsp;//&nbsp;User&nbsp;data<br>&nbsp;string&nbsp;encryptedTicket&nbsp;=&nbsp;FormsAuthentication.Encrypt(authTicket);<br>//&nbsp;创建Cookie<br>HttpCookie&nbsp;authCookie&nbsp;=&nbsp;<br>new&nbsp;HttpCookie(FormsAuthentication.FormsCookieName,<br>encryptedTicket);<br>&nbsp;Response.Cookies.Add(authCookie);&nbsp;<br>&nbsp;//&nbsp;将用户重定向到最初请求页面。<br>Response.Redirect(&nbsp;FormsAuthentication.GetRedirectUrl(<br>txtUserName.Text,&nbsp;<br>false&nbsp;));<br>}<br>}<br>&nbsp;4．&nbsp;创建IPrincipal对象&nbsp;可在Application_AuthenticateRequest事件中创建一个IPrincipal对象，一般使用GenericPrincipal类。<br>5．&nbsp;将IPrincipal对象置于当前的HTTP上下文&nbsp;<br>&nbsp;protected&nbsp;void&nbsp;Application_AuthenticateRequest(Object&nbsp;sender,&nbsp;EventArgs&nbsp;e)<br>{<br>//&nbsp;提去窗体身份验证cookie<br>string&nbsp;cookieName&nbsp;=&nbsp;FormsAuthentication.FormsCookieName;<br>HttpCookie&nbsp;authCookie&nbsp;=&nbsp;Context.Request.Cookies[cookieName];<br>&nbsp;if(null&nbsp;==&nbsp;authCookie)<br>{<br>return;<br>}&nbsp;<br>&nbsp;FormsAuthenticationTicket&nbsp;authTicket&nbsp;=&nbsp;null;<br>try<br>{<br>authTicket&nbsp;=&nbsp;FormsAuthentication.Decrypt(authCookie.Value);<br>}<br>catch(Exception&nbsp;ex)<br>{<br>return;<br>}<br>&nbsp;if&nbsp;(null&nbsp;==&nbsp;authTicket)<br>{<br>return;&nbsp;<br>}&nbsp;<br>&nbsp;//提取角色<br>string[]&nbsp;roles&nbsp;=&nbsp;authTicket.UserData.Split(new&nbsp;char[]{'|'});<br>&nbsp;//&nbsp;创建Identity&nbsp;object<br>FormsIdentity&nbsp;id&nbsp;=&nbsp;new&nbsp;FormsIdentity(&nbsp;authTicket&nbsp;);&nbsp;<br>&nbsp;GenericPrincipal&nbsp;principal&nbsp;=&nbsp;new&nbsp;GenericPrincipal(id,&nbsp;roles);<br>Context.User&nbsp;=&nbsp;principal;<br>}<br>&nbsp;具体的代码读者可以自行补充完成。<br>5.&nbsp;后记与授权与安全通讯有关的内容将另外论述。&nbsp;－－－－－－－－－－－－－－－－－－－－－－&nbsp;服务器安全讨论区&nbsp;<a href="http://www.safe263.cn/" target=_blank><u><font color=#0000ff>http://www.safe263.cn</font></u></a>&nbsp;<br>&nbsp;<br></div>
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/132603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-07-26 17:59 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WindowsXP 系统登陆原理及其验证机制概述 zz</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132600.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Thu, 26 Jul 2007 09:58:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132600.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/132600.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132600.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/132600.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/132600.html</trackback:ping><description><![CDATA[<p><span id=ArticleContent1_ArticleContent1_lblContent>平常我们在使用WindowsXP时，总是要先进行登录。WindowsXP的登录验证机制和原理都要比Windows98严格并复杂得多，不会再出现按&#8220;取消&#8221;按钮就能进入系统的丑事（可以通过修改注册表来禁止）。理解并掌握WindowsXP的登录验证机制和原理对我们来说很重要，能增强对系统安全的认识，并能够有效预防、解决黑客和病毒的入侵。<br>一、了解WindowsXP的几种登录类型。<br>1、交互式登录<br>　　 交互式登录是我们平常最常见类型，就是用户通过相应的用户帐号(User Account)和密码在本机进行登录。有些网友认为&#8220;交互式登录&#8221;就是&#8220;本地登录&#8221;，其实这是错误的。&#8220;交互式登录&#8221;还包括&#8220;域帐号登录&#8221;，而&#8220;本地登录&#8221;仅限于&#8220;本地帐号登录&#8221;，详细讲解请参看下文。<br>　　这里有必要提及的是，通过终端服务和远程桌面登录主机，可以看作&#8220;交互式登录&#8221;，其验证的原理是一样的。<br>　　在交互式登录时，系统会首先检验登录的用户帐号类型，是本地用户帐号(Local User Account)，还是域用户帐号(Domain User Account)，再采用相应的验证机制。因为不用的用户帐号类型，其处理方法也不同。<br>　◇ 本地用户帐号<br>　　采用本地用户帐号登录，系统会通过存储在本机SAM数据库中的信息进行验证。所以也就为什么Windows2000忘记Administrator密码时可以删除SAM文件的方法来解决。不过对于WindowsXP则不可以，可能是出于安全方面考虑吧。用本地用户帐号登录后，只能访问到具有访问权限的本地资源。（图1）<br><br>　◇域用户帐号<br>　　采用域用户帐号登录，系统则通过存储在域控制器的活动目录中的数据进行验证。如果该用户帐号有效，则登录后可以访问到整个域中具有访问权限的资源。<br>小提示：如果计算机加入域以后，登录对话框就会显示&#8220;登录到：&#8221;项目，可以从中选择登录到域还是登录到本机。<br>2、网络登录<br>　　如果计算机加入到工作组或域，当要访问其他计算机的资源时，就需要&#8220;网络登录&#8221;了。如图2，当要登录名称为Heelen的主机时，输入该主机的用户名称和密码后进行验证。这里需要提醒的是，输入的用户帐号必须是对方主机上的，而非自己主机上的用户帐号。因为进行网络登录时，用户帐号的有效性是由受访主机进行的。<br><br>3、服务登录<br>　　服务登录是一种特殊的登录方式。平时，系统启动服务和程序时，都是先以某些用户帐号进行登录后运行的，这些用户帐号可以是域用户帐号、本地用户帐号或SYSTEM帐号。采用不同的用户帐号登录，其对系统的访问、控制权限也不同，而且，用本地用户帐号登录，只能访问到具有访问权限的本地资源，不能访问到其他计算机上的资源，这点和&#8220;交互式登录&#8221;类似。<br>　　从图3的任务管理器中可以看到，系统的进程所使用的帐号是不同的。当系统启动时，一些基与Win32的服务会被预先登录到系统上，从而实现对系统的访问和控制。运行services.msc，可以设置这些服务。正是系统服务有着举足轻重的地位，它们一般都以SYSTEM帐号登录的，对系统有绝对的控制权限，所以很多病毒和木马也争着加入这个贵族中。除了SYSTEM，有些服务还以Local Service和Network Service这两个帐号登录。而在系统初始化后，用户运行的一切程序都是以用户本身帐号登录的。<br><br>　　从上面讲到的原理不难看出，为什么很多电脑文章告诉一般用户，平时使用计算机时要以Users组的用户登录，因为即使运行了病毒、木马程序，由于受到登录用户帐号相应的权限限制，最多也只能破坏属于用户本身的资源，而对维护系统安全和稳定性的重要信息无破坏性。 <br>4、批处理登录<br>　　批处理登录一般用户很少用到，通常被执行批处理操作的程序所使用。在执行批处理登录时，所用帐号要具有批处理工作的权利，否则不能进行登录。<br><br>　　平常我们接触最多的是&#8220;交互式登录&#8221;，所以下面笔者讲为大家详细讲解&#8220;交互式登录&#8221;的原理。<br><br>二、交互式登录，系统用了哪些组件<br>1、winlogon.exe<br>　　winlogon.exe是&#8220;交互式登录&#8221;时最重要的组件，它是一个安全进程，负责如下工作：<br>　◇加载其他登录组件。<br>　◇提供同安全相关的用户操作图形界面，以便用户能进行登录或注销等相关操作。<br>　◇根据需要，同GINA发送必要信息。<br>2、GINA<br>　　GINA的全称为&#8220;Graphical Identification and Authentication&#8221;??图形化识别和验证。它是几个动态数据库文件，被winlogon.exe所调用，为其提供能够对用户身份进行识别和验证的函数，并将用户的帐号和密码反馈给winlogon.exe。在登录过程中，&#8220;欢迎屏幕&#8221;和&#8220;登录对话框&#8221;就是GINA显示的。<br>　　一些主题设置软件，例如styleXP，可以指定winlogon.exe加载商家自己开发的GINA，从而提供不同的WindowsXP的登录界面。由于这个可修改性，现在出现了盗取帐号和密码的木马。<br>　　一种是针对&#8220;欢迎屏幕&#8221;登录方式的木马，它模拟了WindowsXP的欢迎界面。当用户输入密码后，就被木马程序所获取，而用户却全然不知。所以建议大家不要以欢迎屏幕来登录，且要设置&#8220;安全登录&#8221;。<br>　　另一种是针对登录对话框的GINA木马，其原理是在登录时加载，以盗取用户的帐号和密码，然后把这些信息保存到%systemroot%system32下的WinEggDrop.dat中。该木马会屏蔽系统以&#8220;欢迎屏幕&#8221;方式登录和&#8220;用户切换&#8221;功能，也会屏蔽&#8220;Ctrl-Alt-Delete&#8221;的安全登录提示。<br>　　用户也不用太担心被安装了GINA木马，笔者在这里提供解决方案给大家参考： <br>　◇正所谓&#8220;解铃还需系铃人&#8221;，要查看自己电脑是否安装过GINA木马，可以下载一个GINA木马程序，然后运行InstGina -view，可以查看系统中GinaDLL那键值是否有被安装过DLL，主要用来查看系统是否被人安装了Gina木马作为登录所用。如果不幸被安装了GINA木马，可以运行InstGina -Remove来卸载它。<br>3、LSA服务<br>　　LSA的全称为&#8220;Local Security Authority&#8221;??本地安全授权，Windows系统中一个相当重要的服务，所有安全认证相关的处理都要通过这个服务。它从winlogon.exe中获取用户的帐号和密码，然后经过密钥机制处理，并和存储在帐号数据库中的密钥进行对比，如果对比的结果匹配，LSA就认为用户的身份有效，允许用户登录计算机。如果对比的结果不匹配，LSA就认为用户的身份无效。这时用户就无法登录计算机。<br>　　怎么看这三个字母有些眼熟？对了，这个就是和前阵子闹得沸沸扬扬的&#8220;震荡波&#8221;撤上关系的。&#8220;震荡波&#8221;蠕虫就是利用LSA远程缓冲区溢出漏洞而获得系统最高权限SYSTEM来攻击电脑的。解决的方法网上很多资料，这里就不多讲了。<br>4、SAM数据库<br>　　SAM的全称为&#8220;Security Account Manager&#8221;??安全帐号管理器，是一个被保护的子系统，它通过存储在计算机注册表中的安全帐号来管理和用户和用户组的信息。我们可以把SAM看成一个帐号数据库。对于没有加入到域的计算机来说，它存储在本地，而对于加入到域的计算机，它存储在域控制器上。<br>　　如果用户试图登录本机，那么系统会使用存储在本机上的SAM数据库中的帐号信息同用户提供的信息进行比较；如果用户试图登录到域，那么系统会使用存储在域控制器中上的SAM数据库中的帐号信息同用户提供的信息进行比较。<br>5、Net Logon服务<br>　　Net Logon服务主要和NTLM（NT LAN Manager，Windows NT 4.0 的默认验证协议）协同使用，用户验证Windows NT域控制器上的SAM数据库上的信息同用户提供的信息是否匹配。NTLM协议主要用于实现同Windows NT的兼容性而保留的。<br>6、KDC服务<br>　　KDC（Kerberos Key Distribution Center??Kerberos密钥发布中心）服务主要同Kerberos认证协议协同使用，用于在整个活动目录范围内对用户的登录进行验证。如果你确保整个域中没有Windows NT计算机，可以只使用Kerberos协议，以确保最大的安全性。该服务要在Active Directory服务启动后才能启用。<br>7、Active Directory服务<br>　　如果计算机加入到Windows2000或Windows2003域中，则需启动该服务以对Active Directory（活动目录）功能的支持。<br><br>三、登录前后，winlogon到底干了什么<br>　　如果用户设置了&#8220;安全登录&#8221;，在winlogon初始化时，会在系统中注册一个SAS (Secure Attention Sequence??安全警告序列）。SAS是一组组合键，默认情况下为Ctrl-Alt-Delete。它的作用是确保用户交互式登录时输入的信息被系统所接受，而不会被其他程序所获取。所以说，使用&#8220;安全登录&#8221;进行登录，可以确保用户的帐号和密码不会被黑客盗取。要启用&#8220;安全登录&#8221;的功能，可以运行&#8220;control userpasswords2&#8221;命令，打开&#8220;用户帐户&#8221;对话框，选择&#8220;高级&#8221;。（如图4）选中&#8220;要求用户按Ctrl-Alt-Delete&#8221;选项后确定即可。以后，在每次登录对话框出现前都有一个提示，要求用户按Ctrl-Alt-Delete组合键，目的是为了在登录时出现WindowsXP的GINA登录对话框，因为只有系统本身的GINA才能截获这个组合键信息。而如前面讲到的GINA木马，会屏蔽掉&#8220;安全登录&#8221;的提示，所以如果&#8220;安全登录&#8221;的提示无故被屏蔽也是发现木马的一个前兆。&#8220;安全登录&#8221;功能早在Windows2000时就被应用于保护系统安全性。<br><br>　　在winlogon注册了SAS后，就调用GINA生成3个桌面系统，在用户需要的时候使用，它们分别为：<br>　◇Winlogon桌面 用户在进入登录界面时，就进入了Winlogon桌面。而我们看到的登录对话框，只是GINA负责显示的。如果用户取消以&#8220;欢迎屏幕&#8221;方式登录，在进入WindowsXP中任何时候按下&#8220;Ctrl-Alt-Delete&#8221;，都会激活Winlogon桌面，并显示图5的&#8220;Windows安全&#8221;对话框。（注意，Winlogon桌面并不等同对话框，对话框只是Winlogon调用其他程序来显示的）<br><br>　◇用户桌面 用户桌面就是我们日常操作的桌面，它是系统最主要的桌面系统。用户需要提供正确的帐号和密码，成功登录后才能显示&#8220;用户桌面&#8221;。而且，不同的用户，winlogon会根据注册表中的信息和用户配置文件来初始化用户桌面。<br>　◇屏幕保护桌面 屏幕保护桌面就是屏幕保护，包括&#8220;系统屏幕保护&#8221;和&#8220;用户屏幕保护&#8221;。在启用了&#8220;系统屏幕保护&#8221;的前提下，用户未进行登录并且长时间无操作，系统就会进入&#8220;系统屏幕保护&#8221;；而对于&#8220;用户屏幕保护&#8221;来说，用户要登录后才能访问，不同的用户可以设置不同的&#8220;用户屏幕保护&#8221;。<br><br>四、想登录，也要过GINA这一关<br>　　在&#8220;交互式登录&#8221;过程中，Winlogon调用了GINA组文件，把用户提供的帐号和密码传达给GINA，由GINA负责对帐号和密码的有效性进行验证，然后把验证结果反馈给Winlogon程序。在与Winlogon.exe对话时，GINA会首先确定winlogon.exe的当前状态，再根据不同状态来执行不同的验证工作。通常Winlogon.exe有三中状态：<br>　1、已登录状态<br>顾名思义，用户在成功登录后，就进入了&#8220;已登录状态&#8221;。在此状态下，用户可以执行有控制权限的任何操作。<br>　2、已注销状态<br>用户在已登录状态下，选择&#8220;注销&#8221;命令后，就进入了&#8220;已注销状态&#8221;，并显示Winlogon桌面，而由GINA负责显示登录对话框或欢迎屏幕。<br>　3、已锁定状态<br>当用户按下&#8220;Win+L&#8221;键锁定计算机后，就进入了&#8220;已锁定状态&#8221;。在此状态下，GINA负责显示可供用户登录的对话框。此时用户有两种选择，一种是输入当前用户的密码返回&#8220;已登录状态&#8221;，另一种是输入管理员帐号和密码，返回&#8220;已注销状态&#8221;，但原用户状态和未保存数据丢失。<br><br>五、登录到本机的过程<br>1、用户首先按Ctrl+Alt+Del组合键。 <br>2、winlogon检测到用户按下SAS键，就调用GINA，由GINA显示登录对话框，以便用户输入帐号和密码。<br>3、用户输入帐号和密码，确定后，GINA把信息发送给LSA进行验证。<br>4、在用户登录到本机的情况下，LSA会调用msv1_0.dll这个验证程序包，将用户信息处理后生成密钥，同SAM数据库中存储的密钥进行对比。<br>5、如果对比后发现用户有效，SAM会将用户的SID（Security Identifier??安全标识），用户所属用户组的SID，和其他一些相关信息发送给LSA。<br>6、LSA将收到的SID信息创建安全访问令牌，然后将令牌的句柄和登录信息发送给winlogon.exe。<br>7、winlogon.exe对用户登录稍作处理后，完成了整个登录过程。<br><br>六、登录到域的过程<br>　登录到域的验证过程，对于不同的验证协议也有不同的验证方法。如果域控制器是Windows NT 4.0，那么使用的是NTLM验证协议，其验证过程和前面的&#8220;登录到本机的过程&#8221;差不多，区别就在于验证帐号的工作不是在本地SAM数据库中进行，而是在域控制器中进行；而对于Windows2000和Windows2003域控制器来说，使用的一般为更安全可靠的Kerberos v5协议。通过这种协议登录到域，要向域控制器证明自己的域帐号有效，用户需先申请允许请求该域的TGS（Ticket-Granting Service??票据授予<br>服务）。获准之后，用户就会为所要登录的计算机申请一个会话票据，最后还需申请允许进入那台计算机的本地系统服务。<br><br>其过程如下：<br>1、用户首先按Ctrl+Alt+Del组合键。<br>2、winlogon检测到用户按下SAS键，就调用GINA，由GINA显示登录对话框，以便用户输入帐号和密码。<br>3、用户选择所要登录的域和填写帐号与密码，确定后，GINA将用户输入的信息发送给LSA进行验证。<br>4、在用户登录到本机的情况下，LSA将请求发送给Kerberos验证程序包。通过散列算法，根据用户信息生成一个密钥，并将密钥存储在证书缓存区中。<br>5、Kerberos验证程序向KDC（Key Distribution Center??密钥分配中心）发送一个包含用户身份信息和验证预处理数据的验证服务请求，其中包含用户证书和散列算法加密时间的标记。<br>6、KDC接收到数据后，利用自己的密钥对请求中的时间标记进行解密，通过解密的时间标记是否正确，就可以判断用户是否有效。<br>7、如果用户有效，KDC将向用户发送一个TGT（Ticket-Granting Ticket??票据授予票据）。该TGT（AS_REP）将用户的密钥进行解密，其中包含会话密钥、该会话密钥指向的用户名称、该票据的最大生命期以及其他一些可能需要的数据和设置等。用户所申请的票据在KDC的密钥中被加密，并附着在AS_REP中。在TGT的授权数据部分包含用户帐号的SID以及该用户所属的全局组和通用组的SID。注意，返回到LSA的SID包含用户的访问令牌。票据的最大生命期是由域策略决定的。如果票据在活动的会话中超过期限，用户就必须申请新的票据。<br>8、当用户试图访问资源时，客户系统使用TGT从域控制器上的Kerberos TGS请求服务票据（TGS_REQ)。然后TGS将服务票据（TGS_REP）发送给客户。该服务票据是使用服务器的密钥进行加密的。同时，SID被Kerberos服务从TGT复制到所有的Kerberos服务包含的子序列服务票据中。<br>9、客户将票据直接提交到需要访问的网络服务上，通过服务票据就能证明用户的标识和针对该服务的权限，以及服务对应用户的标识。<br><br>七、我要偷懒??设置自动登录<br>　为了安全起见，平时我们进入WindowsXP时，都要输入帐号和密码。而一般我们都是使用一个固定的帐号登录的。面对每次烦琐的输入密码，有的朋友干脆设置为空密码或者类似&#8220;123&#8221;等弱口令，而这些帐号也多数为管理员帐号。殊不知黑客用一般的扫描工具，很容易就能扫描到一段IP段中所有弱口令的计算机。<br>　所以，还是建议大家要把密码尽量设置得复杂些。如果怕麻烦，可以设置自动登录，不过自动登录也是很不安全的。因为自动登录意味着能直接接触计算机的人都能进入系统；另一方面，帐号和密码是明文保存在注册表中的，所以任何人，只要具有访问注册表的权限，都可以通过网络查看。因此如果要设置登录，最好不要设置为管理员帐号，可以设置为USERS组的用户帐号。设置自动登录的方法是：运行&#8220;control userpasswords2&#8221;，（如图6）<br><br>在&#8220;用户帐户&#8221;窗口中取消&#8220;要使用本机，用户必须输入用户名和密码&#8221;选项，确定后会出现一个对话框，输入要自动登录的帐号和密码即可。注意，这里不对密码进行验证，用户要确保密码和帐号的正确性。<br></span></span></p>
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/132600.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-07-26 17:58 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132600.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows登录过程 winlogon/gina/Kerberos/kdc (zz)</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132599.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Thu, 26 Jul 2007 09:56:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132599.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/132599.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132599.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/132599.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/132599.html</trackback:ping><description><![CDATA[<a href="http://topic.csdn.net/t/20060301/15/4585911.html">http://topic.csdn.net/t/20060301/15/4585911.html</a>#<br><br><br>先说说登录过程吧,首先声明,winlogon.exe可不是随意可更换的,我们更换的是GINA,而非winlogon.exe,如果处理不当,可能WINDOWS就起不来了. &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 在&#8220;交互式登录&#8221;过程中，Winlogon调用了GINA组文件，把用户提供的账号和密码传达给GINA，由GINA负责对账号和密码的有效性进行验证，然后把验证结果反馈给Winlogon程序。在与Winlogon.exe对话时，GINA会首先确定Winlogon.exe的当前状态，再根据不同状态来执行不同的验证工作。通常Winlogon.exe有三种状态： &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　1．已登录状态 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　顾名思义，用户在成功登录后，就进入了&#8220;已登录状态&#8221;。在此状态下，用户可以执行有控制权限的任何操作。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　2．已注销状态 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　用户在已登录状态下，选择&#8220;注销&#8221;命令后，就进入了&#8220;已注销状态&#8221;，并显示Winlogon桌面，而由GINA负责显示登录对话框或欢迎屏幕。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　3．已锁定状态 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　当用户按下&#8220;Win+L&#8221;键锁定计算机后，就进入了&#8220;已锁定状态&#8221;。在此状态下，GINA负责显示可供用户登录的对话框。此时用户有两种选择，一种是输入当前用户的密码返回&#8220;已登录状态&#8221;，另一种是输入管理员账号和密码，返回&#8220;已注销状态&#8221;，但原用户状态和未保存数据丢失。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　////登录到本机的过程 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　1.用户首先按Ctrl+Alt+Del组合键。 &nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　2.Winlogon检测到用户按下SAS键，就调用GINA，由GINA显示登录对话框，以便用户输入账号和密码。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　3.用户输入账号和密码，确定后，GINA把信息发送给LSA进行验证。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　4.在用户登录到本机的情况下，LSA会调用Msv1_0.dll这个验证程序包，将用户信息处理后生成密钥，同SAM数据库中存储的密钥进行对比。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　5.如果对比后发现用户有效，SAM会将用户的SID(Security &nbsp; Identifier--安全标识)，用户所属用户组的SID，和其他一些相关信息发送给LSA。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　6.LSA将收到的SID信息创建安全访问令牌，然后将令牌的句柄和登录信息发送给Winlogon.exe。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　7.Winlogon.exe对用户登录稍作处理后，完成整个登录过程。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　////登录到域的过程 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　登录到域的验证过程，对于不同的验证协议也有不同的验证方法。如果域控制器是Windows &nbsp; NT &nbsp; 4.0，那么使用的是NTLM验证协议，其验证过程和前面的&#8220;登录到本机的过程&#8221;差不多，区别就在于验证账号的工作不是在本地SAM数据库中进行，而是在域控制器中进行；而对于Windows &nbsp; 2000和Windows &nbsp; 2003域控制器来说，使用的一般为更安全可靠的Kerberos &nbsp; V5协议。通过这种协议登录到域，要向域控制器证明自己的域账号有效，用户需先申请允许请求该域的TGS(Ticket-Granting &nbsp; Service--票据授予服务)。获准之后，用户就会为所要登录的计算机申请一个会话票据，最后还需申请允许进入那台计算机的本地系统服务。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　其过程如下： &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　1.用户首先按Ctrl+Alt+Del组合键。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　2.Winlogon检测到用户按下SAS键，就调用GINA，由GINA显示登录对话框，以便用户输入账号和密码。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　3.用户选择所要登录的域和填写账号与密码，确定后，GINA将用户输入的信息发送给LSA进行验证。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　4.在用户登录到本机的情况下，LSA将请求发送给Kerberos验证程序包。通过散列算法，根据用户信息生成一个密钥，并将密钥存储在证书缓存区中。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　5.Kerberos验证程序向KDC(Key &nbsp; Distribution &nbsp; Center--密钥分配中心)发送一个包含用户身份信息和验证预处理数据的验证服务请求，其中包含用户证书和散列算法加密时间的标记。 &nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　6.KDC接收到数据后，利用自己的密钥对请求中的时间标记进行解密，通过解密的时间标记是否正确，就可以判断用户是否有效。 &nbsp; &nbsp; <br>&nbsp; 　　7.如果用户有效，KDC将向用户发送一个TGT(Ticket-Granting &nbsp; Ticket--票据授予票据)。该TGT(AS_REP)将用户的密钥进行解密，其中包含会话密钥、该会话密钥指向的用户名称、该票据的最大生命期以及其他一些可能需要的数据和设置等。用户所申请的票据在KDC的密钥中被加密，并附着在AS_REP中。在TGT的授权数据部分包含用户账号的SID以及该用户所属的全局组和通用组的SID。注意，返回到LSA的SID包含用户的访问令牌。票据的最大生命期是由域策略决定的。如果票据在活动的会话中超过期限，用户就必须申请新的票据。 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　8.当用户试图访问资源时，客户系统使用TGT从域控制器上的Kerberos &nbsp; TGS请求服务票据(TGS_REQ)。然后TGS将服务票据(TGS_REP)发送给客户。该服务票据是使用服务器的密钥进行加密的。同时，SID被Kerberos服务从TGT复制到所有的Kerberos服务包含的子序列服务票据中。 &nbsp; 　　 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 　　9.客户将票据直接提交到需要访问的网络服务上，通过服务票据就能证明用户的标识和针对该服务的权限，以及服务对应用户的标识。&nbsp;&nbsp;&nbsp;<br>&nbsp; 
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/132599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-07-26 17:56 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/07/26/132599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>创业10大病症及疗法</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/07/10/129393.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Tue, 10 Jul 2007 09:13:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/07/10/129393.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/129393.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/07/10/129393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/129393.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/129393.html</trackback:ping><description><![CDATA[一.病名：犹豫症 <br>　　　　病征：现时生活较稳定， <br>　　觉得没意思和没新鲜感，有一种创业的冲动，但又怕万一失败反而比现在还糟糕。 <br>　　<br>　　　　疗法：想清楚自己最愿意过甚么生活。如追求稳定，想办法过得有滋有味就行了，不必自讨苦吃去创业；如是想创业，就要有一去不回头的打算，无论怎么样都要熬下去。 <br>　　<br>　　　　二.病名：茫然症 <br>　　<br>　　　　病征：甚么都想做，甚么都可以做，甚么都有困难，无从下手。 <br>　　<br>　　　　疗法：想清楚自己最喜欢和最擅长（两者皆有最好，有其一也行，没有就先培养一下）甚么，沿这个方向钻下去就是了，不要跟风，不要看别人，360行，行行能赚钱，关键是自己怎么去赚。 <br>　　<br>　　　　三.病名：多疑症 <br>　　<br>　　　　病征：害怕合作伙伴损害自己的利益，处处防范，搞到不欢而散。 <br>　　<br>　　　　疗法：初期为求安心，合作伙伴应在自己熟悉的朋友、同学、同事、亲戚中寻找，但以后只能靠制度和契约保证各方的责权利，因为人会变，感情也会变，变就有不一致的时候，有制度和契约就可以平静地处理或退出，不会造成兄弟反目、朋友变仇人的情况。因此，合伙协议或公司章程的条文一定要考虑清楚，不要公文化了事。 <br>　　<br>　　　　四.病名：老大症 <br>　　<br>　　　　病征：合作各方都认为自己很强，互相不服气，都想当董事长或总经理，当不成就处处显示自己在企业中的影响，达到&#8220;不是老大的老大&#8221;境界最好，成为&#8220;少了我老大就玩不转了&#8221;的人也不错。 <br>　　<br>　　　　疗法：建立&#8220;最没本事的人做老大&#8221;的共识，老大只负责决策和协调，需要真本事的地方由有本事的人完成，如果你自认还有一点本事就别争当老大了。 <br>　　<br>　　　　五.病名：虚荣症 <br>　　<br>　　　　病征：开张依始，就要坐大班台，装修办公室，请小姐接电话&#8230;&#8230;. <br>　　<br>　　　　疗法：先多想想怎么赚得更多，而不是把钱花掉。 <br>　　<br>　　　　六.病名：急躁症 <br>　　<br>　　　　病征：恨不得一天赚100万或更多，一万年太久，只争朝夕 <br>　　<br>　　　　疗法：制定半年甚至一年没钱赚如何坚持下去的计划 <br>　　<br>　　　　七.病名：狂妄症 <br>　　<br>　　　　病征：老子天下第一，一出手就惊天动地大手笔。 <br>　　<br>　　　　疗法：将狂妄加速进行，再从失败中得到教训。 <br>　　<br>　　　　八.病名：消化不良症 <br>　　<br>　　　　病征：每一项生意前景都很好，但现在没有一样作好的 <br>　　<br>　　　　疗法：壮士断臂，集中一点求突破。 <br>　　<br>　　　　九.病名：忧郁症 <br>　　<br>　　　　病征：忧心忡忡，茶饭不思，不知明天会如何。 <br>　　<br>　　　　疗法：与其忧心明天，不如研究明天，一点一滴完善今天，船到桥头自然直。 <br>　　<br>　　　　十.病名：政治症 <br>　　<br>　　　　病征：思考问题和看问题从政治家角度出发，言行如政府官员或党派领袖，牟其中是杰出代表，动不动就到了造福全人类的层次。 <br>　　<br>　　　　疗法：经常问问自己赚了多少，是如何赚的，能不能赚得更多更长远，在商言商，以利益为中心，学会做企业人. <br>
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/129393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-07-10 17:13 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/07/10/129393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IE javascript被禁止，导致bug</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/03/29/107149.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Thu, 29 Mar 2007 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/03/29/107149.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/107149.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/03/29/107149.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/107149.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/107149.html</trackback:ping><description><![CDATA[
		<a href="http://b.zhongsou.com/bbs/newbbs/manage_ip-out.asp"> http://b.zhongsou.com/bbs/newbbs/manage_ip-out.asp</a>
		<br />
		<br />网页中使用javascript进行跳转，<br />但是禁止javascript后，<br />程序继续执行。<br /><br /><br /><br /><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/107149.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-03-29 10:59 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/03/29/107149.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HOW-TO: Adobe Photoshop CS2 on Ubuntu - 8 steps! (zz)</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/03/27/106802.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Tue, 27 Mar 2007 15:40:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/03/27/106802.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/106802.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/03/27/106802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/106802.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/106802.html</trackback:ping><description><![CDATA[
		<p>- What you need?</p>
		<ul>
				<li>A fresh install of Ubuntu Dapper + all the updates 
</li>
				<li>A Windows box with a fully installed and activated version of Adobe Photoshop CS2 </li>
		</ul>
		<p>- Fire up a terminal session and type the next commands;</p>
		<p class="question">
				<strong>TIP: </strong>Instead of using apt-get, you can install them with the Synaptic Package Manager located in the System/Administration menu</p>
		<ul>
				<li>
						<strong>$ sudo apt-get update</strong>
				</li>
				<li>
						<strong>$ sudo apt-get install wine </strong>and then type “yes” 
</li>
				<li>
						<strong>$ sudo wine</strong> /*To create the wine file structure*/ 
</li>
				<li>
						<strong>$ sudo apt-get install recode </strong>and then type “yes” </li>
		</ul>
		<p>- Then you need to copy all the necessary files from the Windows box;</p>
		<ul>
				<li>Copy the whole Adobe folder from <strong>“c:\Program Files\</strong>” to “<strong>/home/YOURNAME/.wine/drive_c/Program Files/”</strong></li>
		</ul>
		<p>- Now you need to export the registry keys of the Adone Photoshop CS2;</p>
		<ul>
				<li>In your Windows box, type <strong>“regedit”</strong> in the command-line and export the whole <strong>“HKEY_LOCAL_MACHINE/Software/Adobe/”</strong> to <strong>“adobe.reg”</strong>. 
</li>
				<li>The next step is to copy that file to your Ubuntu box and convert it to the encoding of <em>YOUR</em> system. For example, if your Ubuntu box has as default charset <em>ascii</em> and your Windows box has <em>ucs-2 </em>then <strong>“$ recode ucs-2..ascii adobe.reg”</strong> would do the trick. After you converted your adobe.reg file, type <strong>“$ sudo wine regedit adobe.reg” </strong>to import it to wine. 
</li>
				<li>That’s it! Type <strong>“$ sudo wine –winver winxp “[path to Photoshop]/photoshop.exe” </strong>or create a launcher and enjoy Adobe Photoshop CS2 on Ubuntu ;) </li>
		</ul>
		<p class="alert">If you are having a problem regarding “<em>unregistered</em>” versions, you will need to <strike>crack</strike> your <strong>photoshop.exe</strong> file. <em><br /></em></p>
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/106802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-03-27 23:40 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/03/27/106802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在线翻译网站大全</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/03/16/104168.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Fri, 16 Mar 2007 02:24:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/03/16/104168.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/104168.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/03/16/104168.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/104168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/104168.html</trackback:ping><description><![CDATA[
		<div class="Content-body" id="logPanel">
				<p>
						<strong>英语翻译网站:</strong>
						<br />
						<a href="http://www.readworld.com/" target="_blank">
								<font color="#000000">http://www.readworld.com</font>
						</a>
						<br />
						<br />中日英互译,还能上载翻译 <br /><a href="http://165net.com/" target="_blank"><font color="#000000">http://165net.com</font></a><br /><br /><a href="http://www.worldlingo.com/" target="_blank"><font color="#000000">http://www.worldlingo.com/</font></a><br /><br /><a href="http://www.netat.net/" target="_blank"><font color="#000000">http://www.netat.net/</font></a><br /><br /><a href="http://www.translate.ru/eng/" target="_blank"><font color="#000000">http://www.translate.ru/eng/</font></a><br /><br /><strong>日语翻译网站</strong><br />1.goo 辞書:收录4部三省堂字典<br /><a href="http://dictionary.goo.ne.jp/index.htmlc">http://dictionary.goo.ne.jp/index.htmlc</a></p>
				<p>2.インフォシーク :支持在线翻译文本和网页<br /><a href="http://www.infoseek.co.jp/Honyaku/">http://www.infoseek.co.jp/Honyaku/</a></p>
				<p>
						<a href="mailto:3.@nifty">3.@nifty</a>翻訳:英和辞典／和英辞典 国語辞典 デジタル用語辞典<br /><a href="http://www.nifty.com/dictionary/?top4">http://www.nifty.com/dictionary/?top4</a></p>
				<p>4.万物大辞典:所有日常用专业辞典<br /><a href="http://www.prcity.co.jp/oichan/dic/index.html">http://www.prcity.co.jp/oichan/dic/index.html</a></p>
				<p>5.在线字典集合网页<br /><a href="http://www.kyotsu.com/level2/culture/dictionary.htm">http://www.kyotsu.com/level2/culture/dictionary.htm</a></p>
				<p>6.Bit.ex日中 中日辞書<br /><a href="http://www.bitex-cn.com/">http://www.bitex-cn.com</a></p>
				<p>7.Kiki's Kanji Dictionary:日汉字发音大全<br /><a href="http://www.kanjidict.com/">http://www.kanjidict.com/</a></p>
				<p>8.楽 語 辞 書:乐器方面的辞典<br /><a href="http://www.cablenet.ne.jp/~atari/music09.htm">http://www.cablenet.ne.jp/~atari/music09.htm</a></p>
				<p>9.ライフサイエンス辞書:提供一些日文输入法的下载及电子辞典部分内容下载<br /><a href="http://lsd.pharm.kyoto-u.ac.jp/FTP3-dos-J.html">http://lsd.pharm.kyoto-u.ac.jp/FTP3-dos-J.html</a><br /><a href="http://lsd.pharm.kyoto-u.ac.jp/Others-J.html">http://lsd.pharm.kyoto-u.ac.jp/Others-J.html</a></p>
				<p>10.日语学习资源发布:日语相关的资料贴子(暴多网站)<br /><a href="http://bbs.online.sh.cn/elitearticle.php?elite_id=231124">http://bbs.online.sh.cn/elitearticle.php?elite_id=231124</a></p>
				<p>11.excite翻訳:支持在线翻译文本<br /><a href="http://www.excite.co.jp/world/text_cn/">http://www.excite.co.jp/world/text_cn/</a></p>
				<p>12.三省堂在线字典<br /><a href="http://www.sanseido.net/">http://www.sanseido.net/</a></p>
				<p>13.カタカナ語:外来语辞典<br /><a href="http://homepage2.nifty.com/YONE/">http://homepage2.nifty.com/YONE/</a></p>
				<p>14.パソコン辞典:电脑专业用语辞典<br /><a href="http://www.qiuyue.com/index.html">http://www.qiuyue.com/index.html</a></p>
				<p>15.デジタル用語辞典:基礎的なパソコン用語から難しい専門用語まで、コンピュータに関連する用語を幅広く収録したインターネット上の用語辞典です<br /><a href="http://yougo.ascii24.com/">http://yougo.ascii24.com/</a></p>
				<p>16.女の子の名前辞書<br /><a href="http://www.dd.iij4u.or.jp/~ume20/f_name/">http://www.dd.iij4u.or.jp/~ume20/f_name/</a></p>
				<p>17.アニメと人形劇のキャラクターのスペル辞典<br /><a href="http://web.kyoto-inet.or.jp/peop">http://web.kyoto-inet.or.jp/peop</a> ... sons/animechara.htm</p>
				<p>18.日语文章汉字假名自动全篇标注<br /><a href="http://www.yaru.com/">http://www.yaru.com/</a></p>
				<p>19.房英類似辞典 外来语研究辞典<br /><a href="http://www.awa.or.jp/home/hiroomi/b-jdic/b-jindex.htm">http://www.awa.or.jp/home/hiroomi/b-jdic/b-jindex.htm</a><br /></p>
		</div>
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/104168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-03-16 10:24 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/03/16/104168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual SourceSafe 教程（zz）</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/02/05/97939.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Mon, 05 Feb 2007 02:57:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/02/05/97939.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/97939.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/02/05/97939.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/97939.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/97939.html</trackback:ping><description><![CDATA[　作为版本控制的管理工具，虽然微软的Visual SourceSafe有许多不尽如人意的地方，这也是很多人所抱怨的。但是我认为，更多时候的使用不便，是因为对工具的不熟悉而导致的。这个教程是笔者在几个月前考察版本控制时根据VSS的联机帮助文档改编而成的。与其说是教程，到不如说是一本简明手册，因为其内容涵盖了VSS的全部功能，并从中提取了自认为重要的和有价值的东西，将之翻译成中文。其中不乏有好的建议和使用技巧，比如：定期备份完整的VSS数据目录，定期清除临时目录的内容，尽量使用一个数据库存放所有文件，使用虚拟回滚（Virtual RollBack）代替普通回滚，排他性签出的使用，Cloak操作等等，不一而足。 
<p>　　对于Branch/Share/Pin/Label这几项功能的融合使用，正文及附录的相关部分提供了相当不错的范例，演示了如何通过灵活运用诸项功能，以自如应对不同的开发场景。笔者在看到这部分内容时，一时间有了恍然大悟之感，心中不禁想到，原来VSS也可以如此用法。相信这些范例对大家也会有不小的启示和“震撼”的。 
</p><p>　　此外，附录部分的“VSS命令-权限级别对应表”是笔者整理之后的结果，有了它，大家对不同权限的用户可以使用何种功能，自会变得一目了然。 
</p><p>　　希望这个教程可以对并不十分熟悉VSS的开发人员和管理人员有所帮助，同时也希望可以借此机会澄清一下大家对VSS的一些“偏见”：） 
</p><hr /><p class="middletitle"></p><table width="450" bgcolor="#cccccc" border="1"><tbody><tr><td><p>　<b>目录</b></p><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#1"><font color="#223355"><u>1 说明</u></font></a><br /><br /><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#2"><font color="#223355"><u>2 概述</u></font></a><br /><br /><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#3"><font color="#223355"><u>3 管理员部分</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#31"><font color="#223355"><u>3.1 维护用户列表</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#311"><font color="#223355"><u>3.1.1 添加用户</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#312"><font color="#223355"><u>3.1.2 更改密码</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#313"><font color="#223355"><u>3.1.3 创建用户列表</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#314"><font color="#223355"><u>3.1.4 删除用户</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#315"><font color="#223355"><u>3.1.5 编辑用户属性</u></font></a></li></ul></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#32"><font color="#223355"><u>3.2 管理数据库</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#321"><font color="#223355"><u>3.2.1 分析数据目录</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#322"><font color="#223355"><u>3.2.2 数据库打包</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#323"><font color="#223355"><u>3.2.3 清除临时目录</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#324"><font color="#223355"><u>3.2.4 锁定数据库</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#325"><font color="#223355"><u>3.2.5 数据库恢复</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#326"><font color="#223355"><u>3.2.6 使用多个数据库</u></font></a></li></ul></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#33"><font color="#223355"><u>3.3 有关权限的话题</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#331"><font color="#223355"><u>3.3.1 权限的传递</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#332"><font color="#223355"><u>3.3.2 安全访问权限</u></font></a></li></ul></li></ul><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#4"><font color="#223355"><u>4 普通用户部分</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#41"><font color="#223355"><u>4.1 对工程、文件的一般性使用</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#411"><font color="#223355"><u>4.1.1 打开/关闭数据库</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#412"><font color="#223355"><u>4.1.2 创建新工程</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#413"><font color="#223355"><u>4.1.3 添加文件、目录、工程</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#414"><font color="#223355"><u>4.1.4 删除和恢复文件、工程</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#415"><font color="#223355"><u>4.1.5 移动文件和工程</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#416"><font color="#223355"><u>4.1.6 重命名文件、工程</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#417"><font color="#223355"><u>4.1.7 设置工作目录</u></font></a></li></ul></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#42"><font color="#223355"><u>4.2 签入、签出、获取、查看及相关操作</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#421"><font color="#223355"><u>4.2.1 签入签出操作</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#422"><font color="#223355"><u>4.2.2 撤销签出</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#423"><font color="#223355"><u>4.2.3 获取最近版本</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#424"><font color="#223355"><u>4.2.4 获取早期版本</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#425"><font color="#223355"><u>4.2.5 获取和查看文件、工程</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#426"><font color="#223355"><u>4.2.6 回滚到以前版本</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#427"><font color="#223355"><u>4.2.7 多人同时签出一个文件</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#428"><font color="#223355"><u>4.2.8 合并</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#429"><font color="#223355"><u>4.2.9 排他性签出</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#42a"><font color="#223355"><u>4.2.10 对工程的Cloak操作</u></font></a></li></ul></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#43"><font color="#223355"><u>4.3 Branch、Share、Label和Pin操作</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#223355"><u>4.3.1 对文件和工程的Branch/Share操作</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#432"><font color="#223355"><u>4.3.2 给文件、工程指定标签</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#433"><font color="#223355"><u>4.3.3 Pin操作</u></font></a></li></ul></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#44"><font color="#223355"><u>4.4 其他操作</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#441"><font color="#223355"><u>4.4.1 扩展关键字</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#442"><font color="#223355"><u>4.4.2 使用Shadow目录</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#443"><font color="#223355"><u>4.4.3 性能优化</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#444"><font color="#223355"><u>4.4.4 查找文件</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#445"><font color="#223355"><u>4.4.5 设置密码</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#446"><font color="#223355"><u>4.4.6 编写批处理文件</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#447"><font color="#223355"><u>4.4.7 定制SS.INI和SRCSAFE.INI文件</u></font></a></li></ul></li></ul><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#a"><font color="#223355"><u>附录</u></font></a><ul><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#a1"><font color="#223355"><u>A1 同时维护一个工程的多个版本</u></font></a></li><li><a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#a2"><font color="#223355"><u>A2 VSS中部分命令的对应权限级别 </u></font></a></li></ul></td></tr></tbody></table><font color="#223355"><u><hr /></u></font><p class="middletitle"><a name="1"><strong><font color="#223355"><br />1 说明</font></strong></a></p><p>一、本教程针对不同使用对象提供Visual SourceSafe 6.0的若干使用指导，阅读对象包括Visual SourceSafe的管理员和普通用户，以及希望了解如何采用Visual SourceSafe进行软件版本控制的管理人员。管理员或普通用户在使用Visual SourceSafe的过程中，如果遇到不知如何操作，或者对某些操作的注意事项不甚了解等类似情况时，可以查阅本教程。</p><p>二、本教程的"管理员部分"是管理员必读的，如果管理员在除履行其自身职责之外，还兼任普通用户的角色，则可以参阅教程中的"普通用户部分"。作为一般的普通用户，只需阅读"普通用户部分"即可。</p><p>三、教程中列举的操作，加星号者，为高级用法（Advanced Usage），其余为基本用法（Basic Usage）。所谓基本用法是指一些通常使用频繁的，或者是使用方法较为简单的操作。所谓高级用法是指通常使用频率不多，或者较为重要的，或者用法复杂的操作。</p><p>四、本教程内容摘选并改编自Visual SourceSafe 6.0英文版联机帮助，从中提取了诸多重要信息、容易忽略的内容以及若干注意事项。一些基本内容（主要指某些基本操作的使用方法）只简单列举了条目，欲了解这些条目的详细情况请查看联机帮助的相关部分，可以通过列于这些条目之后的英文说明在联机帮助中搜索到相关内容。</p><p>五、本教程不涉及Visual SourceSafe图形用户界面操作的解释说明，对指定功能的具体操作步骤请查看联机帮助的相关部分。可以通过列于该功能之后的英文说明在联机帮助中搜索到相关内容。</p><p>六、在其他Visual Studio产品中（例如：Visual C++）可以集成Visual SourceSafe的功能，本教程不涉及有关在其他集成开发环境下如何使用Visual SourceSafe功能的内容，这部分内容主要针对普通用户。对这些内容的了解，在阅读完本教程之后，将会变得容易。此外，某些操作在Visual SourceSafe环境下使用更为方便。</p><p class="middletitle"><a name="2"><strong><font color="#223355">2 概述</font></strong></a></p><p>　　Visual SourceSafe（以下简称VSS）是一种版本控制管理工具。它通过将各种类型的文件（包括：文本文件、图像文件、二进制文件、声音文件、视频文件等）存入其内部数据库的方式，帮助你有效地管理工程（Project，关于VSS中工程的概念请见下面）。它允许你在多个工程间共享同一组文件；你可以将一个文件添加到数据库中，以便其他相关人员使用；任何对文件的更改将被记录下来，以便在任何时候可以恢复到该文件的某个旧版本。</p><p>　　VSS的工程组织方式使团队协作开发变得更为容易和直观。<em class="important">一个工程是一组存放于VSS数据库内的任意类型的文件，一个工程类似于操作系统中的目录，但VSS为其提供了版本控制、历史记录、文件合并等更多的功能支持。</em></p><p class="middletitle"><a name="3"><strong><font color="#223355">3 管理员部分</font></strong></a></p><p class="middletitle"><a name="31">3.1 维护用户列表(Maintain the User List)</a></p><p class="middletitle"><a name="311">3.1.1 添加用户(Add a User)</a></p><p class="middletitle">　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="312">3.1.2 更改密码(Change Passwords)</a></p><p class="middletitle">　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="313">3.1.3 创建用户列表(Create a User List)</a></p><p class="middletitle">　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="314">3.1.4 删除用户(Delete a User)</a></p><p class="middletitle">　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="315">3.1.5 编辑用户属性(Edit User Attributes)</a></p><p class="middletitle">　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="32">3.2 管理数据库(Manage the Database)</a></p><p class="middletitle"><a name="321">3.2.1 分析数据目录(Analyze the Data Folder)*<br />建议你定期备份完整的VSS数据目录（参见数据库打包）。VSS数据目录中包含有全部工程和文件的数据库信息。由于网络或操作系统的某些故障，VSS中的文件可能存在错误和不一致问题，Analyze VSS DB工具被用来查找和修复这些问题。在运行该工具前，需要锁定（Lock）所有用户并要求他们退出VSS，用户可以在一个数据库被锁定时保持文件的签出状态（参见锁定数据库）。建议分两次运行Analyze VSS DB工具，第一次修复错误，第二次核查是否仍然存在没有被修复的错误。数据目录的具体位置是由Data_Path初始化变量在SRCSAFE.INI文件中指定的（参见定制SS.INI和SRCSAFE.INI文件）。</a></p><p class="middletitle"><a name="322">3.2.2 数据库打包(Archive Databases)*</a></p><p class="middletitle">　　你可能需要定期地备份VSS数据库，或者数据库的某一部分。VSS Administrator工具提供了此项功能。它可以： </p><p class="middletitle">节省VSS数据库服务器的磁盘空间。 <br />加快显示历史记录操作（Show History）的速度。 <br />便于在多个VSS数据库间传递文件和工程，保持历史记录完整无缺。 <br />备份全部或部分VSS数据库内容并压缩成文件。 <br /><br /><a name="323">3.2.3 清除临时目录(Clean Temporary Folder)</a></p><p class="middletitle">　　VSS通常在运行时把临时结果放在临时目录里，并在退出前将之删除。由于某些原因，例如非正常重启，可能导致临时内容残留在目录中。作为管理员，你有责任定期清除临时目录的内容。每隔几周一次，当没有任何用户运行VSS或VSS Administrator时，请清除临时目录的内容。临时目录的具体位置是由Temp_Path初始化变量在SRCSAFE.INI文件中指定的（参见定制SS.INI和SRCSAFE.INI文件）。 </p><p class="middletitle"><a name="324">3.2.4 锁定数据库(Lock a Database)</a></p><p class="middletitle">　　数据库锁定功能将不会自动锁定那些当前已经登录的用户，你应该在锁定数据库之前要求登录用户退出VSS。在重新允许用户使用VSS之前，需要解除对数据库的锁定。<br /><br /><br /><a name="325">3.2.5 数据库恢复(Restore Databases)</a></p><p class="middletitle">　　此处略，详细内容请查阅联机帮助。<br /><br /><a name="326">3.2.6 使用多个数据库(Work with Multiple Databases)*</a></p><p class="middletitle">　　缺省时，VSS将所有文件集中放在一个数据库中。如果可能，应尽量使用一个数据库存放所有文件，这比分多个数据库存放要好，因为： <br />你不能在多个数据库间共享（Share）文件（参见对文件和工程的Branch/Share操作）。 <br />将位于多个数据库中的内容集中在一起是比较困难的，需要使用VSS Administrator的Archive功能（参见数据库打包）。 <br />出于安全的考虑，VSS的用户信息，包括密码在内，是和数据一起存放的。<br />如果为了安全起见，要将信息拆分成多个独立的数据库，<br /><br />　　缺省时，VSS将所有文件集中放在一个数据库中。如果可能，应尽量使用一个数据库存放所有文件，这比分多个数据库存放要好，因为：你不能在多个数据库间共享（Share ）文件（参见对文件和工程的Branch/Share操作）。 <br />将位于多个数据库中的内容集中在一起是比较困难的，需要使用VSS Administrator 的Archive功能（参见数据库打包）。 <br />出于安全的考虑，VSS的用户信息，包括密码在内，是和数据一起存放的。如果为了安全起见，要将信息拆分成多个独立的数据库，这种信息存储方式将带来极大的便利,但你必须为每个数据库都单独添加用户。 <br /><br /><br /><a name="33">3.3 有关权限的话题(About Rights)</a></p><p class="middletitle"><a name="331">3.3.1 权限的传递(Rights Propagation)</a></p><p class="middletitle">　　当你添加了一个新用户，并为该用户设置了针对某个工程的权限时，将在VSS数据库中建立起一个assignment。该 assignment将会沿着工程树向下传递直至遇到另一个assignment。</p><p class="middletitle">　　例如：针对工程"$/" ，你为用户A指定了Add权限（参见安全访问权限），而对于工程"$/Sample"，你没有为用户显式指定权限，则该用户将对工程"$/Sample"自动拥有Add权限。当你在工程"$/Sample/BusinessObject"处为其指定了Read权限后，将阻止早先assignment的向下传递过程，所以用户A对该工程（指"$/Sample/BusinessObject"）及其子工程都只具有Read权限了。</p><p class="middletitle">　　当你首次添加一个用户时，该用户在工程"$/"处被赋予的权限由"缺省权限"决定，缺省权限是通过在VSS Administrator里设置Project Security属性页的内容来定义的。你可以通过修改该页内容，全局性地变更所有用户的缺省权限。</p><p class="middletitle"><a name="332">3.3.2 安全访问权限(Security Access Rights)</a></p><p class="middletitle"><a name="3321">3.3.2.1 缺省安全设置</a></p><p class="middletitle">　　当安装VSS后，缺省安全设置将被启用。你可以利用定制的方式，使某些用户拥有对某些工程和某些VSS命令的特定权限。</p><p class="middletitle">　　缺省安全设置很简单，当添加新用户时，你只有两种级别的访问权限可供选择： </p><p class="middletitle">只读权限（Read-only rights）：用户可以查看VSS中的任何内容，但不能更改。 <br />可读写权限（Read/write rights）：用户可以查看和修改VSS中的任何内容。 </p><p class="middletitle">　　如果这样的访问权限级别足以应对日常使用，那么就无需再增强安全控制的级别了。</p><p class="middletitle">　　所有的VSS安全管理都在VSS Administrator中进行。任何能运行该程序的用户都可以改变VSS的任意特性，所以最好只有管理员才使用该程序。</p><p class="middletitle"><a name="3322">3.3.2.2 更高级别的安全控制</a></p><p class="middletitle">　　在VSS中，对工程的安全性控制，是通过制定用户访问权限来实现的。每个工程仅能被那些具有相应权限的用户访问到，每个命令仅能被那些具有相应权限的用户使用。可以通过VSS Administrator来定制权限，以达到更高级别的安全控制。</p><p class="middletitle">　　以下是VSS的权限级别列表，下列每种权限都拥有该权限之前的全部权限。例如：拥有Check Out权限的用户，也将同时拥有Read权限。（参见附录A2：VSS中部分命令的对应权限级别）</p><p class="middletitle">权限 描述 <br />Read (R) 类似于缺省安全设置中的只读权限 <br />Check Out (C) 可以使用Check Out/Check In/Undo Check Out等命令对文件进行修改 <br />Add (A) 可以使用Add/Delete/Label/Rename等命令对文件进行修改 <br />Destroy(D) 可以使用 Destroy/Purge/Rollback等命令对文件实施永久删除操作 <br /></p><p class="middletitle"><a name="4"><strong>4 普通用户部分</strong></a></p><p class="middletitle"><a name="41"><strong><font color="#223355">4.1 对工程、文件的一般性使用(Normal Use about Projects and Files)</font></strong></a></p><p class="middletitle"><a name="411"><strong>4.1.1 打开/关闭数据库(Open/Close a Database)</strong></a></p><p>　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="412"><strong>4.1.2 创建新工程(Create New Projects)</strong></a></p><p>　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="413"><strong>4.1.3 添加文件、目录、工程(Add Files，Folders，and Projects)</strong></a></p><p>　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="414"><strong>4.1.4 删除和恢复文件、工程(Delete and Recover Files and Projects)</strong></a></p><p>　　VSS提供了3种删除文件的方法： 
</p><ul><li>Delete：VSS只把指定文件从当前工程中删除，而在VSS数据库中仍留有该文件的记录。此外，其他共享了该文件的工程仍保留此文件（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#000080"><u>对文件和工程的Branch/Share操作</u></font></a>）。 
</li><li>Destroy：VSS将把指定文件从VSS数据库中彻底删除，其后将无法恢复。 
</li><li>Purge：永久性删除已被Delete掉的文件，其后将无法恢复。 </li></ul><p></p><p>　　对于共享文件，Delete和Destroy仅将文件从当前所选工程中删除掉，其他共享了该文件的工程，以及VSS数据库中，仍留有此文件。 </p><p class="middletitle"><a name="415"><strong><font color="#223355">4.1.5 移动文件和工程(Move Files and Projects) </font></strong></a></p><p>　　移动一个文件的唯一方法是，在文件新所在位置的上一级工程（parent project）处使该文件共享（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#000080"><u>对文件和工程的Branch/Share操作</u></font></a>），然后将原有工程（original project）下的该文件Delete或者 Destroy（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#414"><font color="#000080"><u>删除和恢复文件、工程</u></font></a>）。移动后，文件的历史记录将被保留。 </p><p>　　通过使用Move命令，你可以将一个子工程（subproject）从某个上级工程重置到另一个工程下。该操作不会改变子工程的内容和历史记录，但它会影响上级工程的历史记录（包括子工程所在的原有上级工程和新的上级工程）。当移动一个工程后，你将无法重建原有上级工程的某个旧版本。</p><p class="middletitle"><a name="416"><strong><font color="#223355">4.1.6 重命名文件、工程(Rename Files or Projects) </font></strong></a></p><p>　　若某个文件被多个工程所共享，对该文件的重命名将影响所有工程，而在Branch状态下，则不影响（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#000080"><u>对文件和工程的Branch/Share操作</u></font></a>）。</p><p class="middletitle"><a name="417"><strong><font color="#223355">4.1.7 设置工作目录(Set Working Folders)</font></strong></a></p><p>　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="42"><strong>4.2 签入、签出、获取、查看及相关操作(Check In/Out、Get、View and Other Related Use) </strong></a></p><p class="middletitle"><a name="421"><strong>4.2.1 签入签出操作(Check In and Check Out Files)</strong></a></p><p>　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="422"><strong>4.2.2 撤销签出(Undo Check Out)</strong></a></p><p>　　执行该操作时，若用户选择了替换本地文件，则用户将丢失最近一次签出后对该文件在本地的更改。</p><p class="middletitle"><a name="423"><strong>4.2.3 获取最近版本(Get Latest Version)</strong></a></p><p>　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="424"><strong>4.2.4 获取早期版本(Get Earlier Version)</strong></a></p><p>　　此处略，详细内容请查阅联机帮助。</p><p class="middletitle"><a name="425"><strong>4.2.5 获取和查看文件、工程(Get and View Files and Projects)</strong></a></p><p>　　Get操作将文件或工程拷贝至本地的工作目录，并设置为read-only属性。可以用View操作查看文件内容，此时用户无需设置工作目录。 </p><p>　　尽量不要删除vssver.scc文件。本地工作目录及每个子目录下都包含一个这样的文件，VSS利用其中记录的信息确定本地目录中哪个文件已经更改了。删除后，将使新一次的Get操作速度减慢。</p><p class="middletitle"><a name="426"><strong>4.2.6 回滚到以前版本(Rollback to Previous Versions)</strong></a></p><p>　　该操作将使文件的内容恢复到先前某个版本时的状态，它将使所有在该版本后所做的改动丢失。如果你所回滚的文件被多个工程共享，则操作只影响你所指定的那个工程，并且它会自动实行Branch操作（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#000080"><u>对文件和工程的 Branch/Share操作</u></font></a>）。建议你使用虚拟回滚（Virtual Rollback），它将不会使随后的改动永久丢失。具体操作如下： 
</p><ul><li>选择你要回滚的文件并签出 
</li><li>使用Get命令获取某个原有版本到本地 
</li><li>签入该文件 </li></ul><p></p><p class="middletitle"><a name="427"><strong><font color="#223355">4.2.7 多人同时签出一个文件(Check Out Multiple Files) *</font></strong></a></p><p>　　缺省状态下，一个文件只允许一个人签出，管理员可以通过修改配置，允许多人同时签出。此时，VSS将跟踪所有签出该文件的用户。每当用户签入时，VSS都将和当前存于数据库内的最新版本进行比较，若用户修改的是同一文件的不同处，VSS将进行简单的合并（Merge），否则提示用户，并且不允许签入。用户可以通过VSS提供的Visual Merge工具，比较存放于VSS数据库中的文件和本地文件的异同，手工修改本地文件，直到认为已经可以签入时，方才执行最终签入操作。（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#428"><font color="#000080"><u>合并</u></font></a>）</p><p class="middletitle"><a name="428"><strong><font color="#223355">4.2.8 合并(Merge)*</font></strong></a></p><p>　　在VSS中，合并可能发生在3种场合下：使用Multiple Checkout的工作方式；合并原先已经Branch了的文件；获取（Get）文件。 
</p><ul><li>Multiple Checkout：若多个用户同时签出一个文件，第一个用户只要简单的签入就可以了。后续用户也可以签入，但他们的更改将需要和其他所有用户的更改合并，VSS将得到完整的更改内容（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#427"><font color="#000080"><u>多人同时签出一个文件 </u></font></a>）。 
</li><li>Branch：当被Branch的文件合并到其中一个分支时，VSS将会把在另一个分支上所做的改动合并到该分支上（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#223355"><u>对文件和工程的Branch/Share操作</u></font></a>）。 
</li><li>Merge on Get：在Multiple Checkout工作方式下，当使用Get Latest Version操作时可能引发合并操作，此时保存在VSS数据库中的内容将合并到本地文件。但如果某个文件是排他性签出的，则不会引发合并操作（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#429"><font color="#223355"><u>排他性签出 </u></font></a>）。 </li></ul><p></p><p>　　在完成一个合并之后，VSS遵循如下规则： 
</p><ul><li>如果仍有冲突，VSS维持文件的签出状态，为了使文件能顺利签入，你必须排除这些冲突。 
</li><li>如果你使用Merge Branches命令，将一个文件合并到一个工程中，而该工程中的对应文件已被签出，该文件将继续保持签出状态（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#223355"><u>对文件和工程的Branch/Share操作</u></font></a>）。 
</li><li>在任何其他时候，VSS将会提示你，或者在合并后自动签入，或者保持文件的签出状态以使你在更新VSS数据库中内容之前再核查一边。 </li></ul><p></p><p>　　缺省情况下，当发生冲突时，VSS将启用其Visual Merge工具。</p><p class="middletitle"><a name="429"><strong><font color="#223355">4.2.9 排他性签出(Exclusive Check Out)*</font></strong></a></p><p>　　允许多人同时签出一个文件是针对整个VSS数据库而言的，但用户仍可以根据实际情况，针对某些文件修改该规则。对某个文件实施排他性签出，则其他用户将无法签出该文件，直至该用户使用了签入操作。</p><p class="middletitle"><a name="42a"><strong>4.2.10 对工程的Cloak操作(Cloak Projects)*</strong></a></p><p>　　若对某工程实行了Cloak操作，则当对该工程的上一级工程进行Get/Check In/Check Out/Undo Check Out/Project Difference操作时，将不会影响该工程及其子工程。而在该工程上进行类似操作时，则和平常得到的结果一样。这一属性将传递给其下的子工程。</p><p>　　例如：某个工程其路径为$/Application，下面有三个子工程：$/Application/Code，$/Application/Test，