﻿<?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>Sat, 20 Mar 2010 06:28:37 GMT</lastBuildDate><pubDate>Sat, 20 Mar 2010 06:28:37 GMT</pubDate><ttl>60</ttl><item><title>劳动法分析</title><link>http://www.blogjava.net/jinfeng_wang/archive/2010/03/19/315853.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Thu, 18 Mar 2010 16:27:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2010/03/19/315853.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/315853.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2010/03/19/315853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/315853.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/315853.html</trackback:ping><description><![CDATA[&nbsp;
<p>A)<span style="font-family: 'ＭＳ 明朝'">中</span><span style="font-family: SimSun">华</span><span style="font-family: 'ＭＳ 明朝'">人民共和国</span><span style="font-family: SimSun">劳动</span><span style="font-family: 'ＭＳ 明朝'">合同法</span></p>
<p><a href="http://www.molss.gov.cn/gb/news/2007-06/30/content_184630.htm">http://www.molss.gov.cn/gb/news/2007-06/30/content_184630.htm</a></p>
<p>B)<span style="font-family: 'ＭＳ 明朝'">中</span><span style="font-family: SimSun">华</span><span style="font-family: 'ＭＳ 明朝'">人民共和国</span><span style="font-family: SimSun">劳动</span><span style="font-family: 'ＭＳ 明朝'">合同法</span><span style="font-family: SimSun">实</span><span style="font-family: 'ＭＳ 明朝'">施条例</span><span style="font-family: 'ＭＳ 明朝'">(</span><span style="font-family: SimSun">解释劳动法实施</span><span style="font-family: 'ＭＳ 明朝'">)</span></p>
<p><a href="http://www.gov.cn/flfg/2008-09/19/content_1099500.htm">http://www.gov.cn/flfg/2008-09/19/content_1099500.htm</a></p>
<p>C)<span style="font-family: SimSun">关于确立劳动关系有关事项的通知</span></p>
<p><a href="http://www.law-lib.com/law/law_view.asp?id=92395">http://www.law-lib.com/law/law_view.asp?id=92395</a></p>
<p>D)<span style="font-family: SimSun">上海市女职工劳动保护办法</span></p>
<p><a href="http://www.shanghai.gov.cn/shanghai/node2314/node3124/node3125/node3133/userobject6ai655.html">http://www.shanghai.gov.cn/shanghai/node2314/node3124/node3125/node3133/userobject6ai655.html</a></p>
<p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>C)</strong></span><strong><span style="font-family: SimSun">的相关内容：</strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-family: SimSun">用人单位未与劳动者签订劳动合同，<strong><span style="color: red">认定双方存在劳动关系</strong>时可参照下列凭证：</span></span></p>
<p>(<span style="font-family: SimSun">一</span>)<span style="font-family: SimSun">工资支付凭证或记录</span>(<span style="font-family: SimSun">职工工资发放花名册</span>)<span style="font-family: SimSun">、缴纳各项社会保险费的记录；</span></p>
<p>(<span style="font-family: SimSun">二</span>)<span style="font-family: SimSun">用人单位向劳动者发放的<strong><span style="color: red">&#8220;工作证&#8221;、&#8220;服务证&#8221;等能够证明身份的证件</strong>；</span></span></p>
<p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>B) </strong></span><strong><span style="font-family: SimSun">的相关内容：</strong></span></p>
<p style="margin-left: 69pt; text-indent: -48pt; tab-stops: list 69.0pt">第六条<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">用人单位自用工之日起<span style="color: blue">超过一个月不满一年</span>未与劳动者订立书面劳动合同的，应当依照<span style="color: blue">劳动合同法第八十二条的规定向劳动者每月支付两倍的工资，并与劳动者补订书面劳动合同</span>；劳动者不与用人单位订立书面劳动合同的，用人单位应当书面通知劳动者终止劳动关系，<span style="color: blue">并依照劳动合同法第四十七条的规定支付经济补偿</span>。</span></span><strong><span style="color: red">(1</strong></span><strong><span style="color: red; font-family: SimSun">，相当于给</strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">倍工资，</strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">，补合同，</strong></span><strong><span style="color: red">3</strong></span><strong><span style="color: red; font-family: SimSun">，如果辞退，再按照有合同补偿）</strong></span></p>
<p style="margin-left: 21pt"><span style="font-family: SimSun">第二十七条　劳动合同法第四十七条规定的<strong><span style="color: red">经济补偿的月工资按照劳动者应得工资计算，包括计时工资或者计件工资以及奖金</strong><span style="color: red">。</span></span></span></p>
<p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>A)</strong></span><strong><span style="font-family: SimSun">的相关内容：</strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">第四十二条　劳动者有下列情形之一的，用人单位<strong><span style="color: red">不得依照</strong>本法第四十条、第四十一条的规定解除劳动合同：</span></span></p>
<p><strong><span style="color: red">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;</strong></span><strong><span style="color: red; font-family: SimSun">（四）女职工在孕期、产期、哺乳期的</strong></span></p>
<p>&nbsp;<span style="font-family: SimSun">　第四十七条　经济补偿按劳动者在本单位工作的年限，<strong><span style="color: red">每满一年支付一个月工资的标准向劳动者支付。六个月以上不满一年的，按一年计算；</strong>不满六个月的，向劳动者支付半个月工资的经济补偿。</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">第八十二条　<strong><span style="color: red">用人单位自用工之日起超过一个月不满一年未与劳动者订立书面劳动合同的，应当向劳动者每月支付二倍的工资。</strong></span></span></p>
<p><strong><span style="color: red">&nbsp;&nbsp;&nbsp; </strong></span><span style="font-family: SimSun">用人单位违反本法规定不与劳动者订立<strong><span style="color: red">无固定期限劳动合同</strong>的，自应当订立无固定期限劳动合同之日起向劳动者每月<strong><span style="color: red">支付二倍的工资</span></strong>。</span></span></p>
<p><strong><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp; </strong></span><span style="font-family: SimSun">第八十七条　用人<strong><span style="color: red">单位违反本法</strong>规定解除或者终止劳动合同的，应当<strong><span style="color: red">依照本法第四十七条</span></strong>规定的经济补偿<strong><span style="color: red">标准的二倍</span></strong>向劳动者支付赔偿金。</span></span></p>
<p>&nbsp;<span style="font-family: SimSun">第十四条　无固定期限劳动合同，是指用人单位与劳动者约定无确定终止时间的劳动合同。</span></p>
<p>&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">用人单位与劳动者协商一致，可以订立无固定期限劳动合同。有下列情形之一，劳动者提出或者同意续订、订立劳动合同的，除劳动者提出订立固定期限劳动合同外，应当<strong><span style="color: red">订立无固定期限劳动合同</strong>：</span></span></p>
<p>&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">（一）劳动者在该用人单位<span style="color: red">连续<strong>工作满十年</strong>的；</span></span></p>
<p>&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">（二）用人单位初次实行劳动合同制度或者国有企业改制重新订立劳动合同时，劳动者在该用人单位连续工作满十年且距法定退休年龄不足十年的；</span></p>
<p>&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">（三）<strong><span style="color: red">连续订立二次固定期限劳动合同</strong>，且劳动者没有本法第三十九条和第四十条第一项、第二项规定的情形，续订劳动合同的。</span></span></p>
<p>&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">用人单位<strong><span style="color: red">自用工之日起满一年不与劳动者订立书面劳动合同的，视为用人单位与劳动者已订立无固定期限劳动合同</strong>。</span></span></p>
<p><strong>&nbsp;</strong></p>
<p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>D) </strong></span><strong><span style="font-family: SimSun">的相关内容：</strong></span></p>
<p><span style="font-family: SimSun">第十一条</span><span style="font-family: SimSun">对妊娠期的女职工，<strong><span style="color: red">不应延长其劳动时间</strong>；</span></span></p>
<p><span style="font-family: SimSun">第十四条</span><span style="font-family: SimSun">女职工产假分别按下列情况执行：</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: SimSun">（一）单胎顺产者，给予<span style="color: red">产假九十天，其中产前休息十五天，产后休息七十五天。</span></span></p>
<p><span style="font-family: SimSun">第十五条</span><span style="font-family: SimSun">女职工生育后，在其婴儿一周岁内应照顾其在每班劳动时间内<span style="color: red">授乳两次（包括人工喂养）。<span style="color: red">每次</span>单胎纯授乳时间为<span style="color: red">三十分钟</span>，亦可将两次授乳时间合并使用。多胞胎生育者，每多生一胎，每次哺乳时间增加三十分钟。</span></span></p>
<p>&nbsp;<span style="font-family: SimSun">第十八条</span><span style="font-family: SimSun">女职工在<span style="color: red">产假期间的工资照发。按本规定享受的<span style="color: red">产前假和哺乳假的工资</span>按本人原工资的<span style="color: red">百分之八十发给</span>。单位增加工资时，女职工按规定享受的产前假、产假、哺乳假，应作出勤对待。</span></span></p>
<p><strong><span style="color: red">&nbsp;&nbsp;&nbsp; </strong></span></p>
<p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: SimSun">结论：</span></strong></span></p>
<p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">1）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="color: red; font-family: SimSun">认定劳动关系：工作证</span></strong></span></p>
<p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">2）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="color: red; font-family: SimSun">是否签合同</span></strong></span></p>
<p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">3）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="color: red; font-family: SimSun">如果没签合同，怎么补偿（</span></strong></span><span style="color: red">1</span><span style="color: red; font-family: SimSun">，<strong>相当于给</strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">倍工资，</strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">，补合同，</strong></span><strong><span style="color: red">3</strong></span><strong><span style="color: red; font-family: SimSun">，如果辞退，再按照有合同补偿）</strong></span></p>
<p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">4）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="color: red; font-family: SimSun">如果是固定合同，怎么补偿（</span></strong></span><strong><span style="color: red">N+1</strong></span><strong><span style="color: red; font-family: SimSun">）</strong></span></p>
<p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">5）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="color: red; font-family: SimSun">如果是无期合同，</span></strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">倍</strong></span></p>
<p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">6）<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="color: red; font-family: SimSun">孕妇怎么处理？</span></strong></span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333">1</span><span style="background: silver; color: #333333; font-family: SimSun">、公司辞退孕妇的补偿情况标准是怎样？</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">答：发放工资到哺乳期满；按工作年限计算经济补偿金。</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333">2</span><span style="background: silver; color: #333333; font-family: SimSun">、公司是否可以以我的考核和我是孕产妇不能胜任工作为由对我进行降职降级降薪处理？</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">答：不可以。</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">我们的工资分为基本工资（约占</span><span style="background: silver; color: #333333">1/4)+</span><span style="background: silver; color: #333333; font-family: SimSun">岗位工资</span><span style="background: silver; color: #333333">+</span><span style="background: silver; color: #333333; font-family: SimSun">绩效工资等。是否可能出现只要不降低我的基本工资就是合法的行为？</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">答：不合理。工资是包括了岗位工资和绩效工资。</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333">3</span><span style="background: silver; color: #333333; font-family: SimSun">、如果公司依法破产，我是否有向集团主张赔偿的权利？</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">答：破产也可以主张权利，在破产财产中优先演戏偿。</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333">4</span><span style="background: silver; color: #333333; font-family: SimSun">、如果可能需要诉诸法律，我应该准备哪些方面的举证？</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">答：存在劳动关系的证据最重要，此外，工资条、怀孕的证据、结婚证、准生证</span></p>
<p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">也比较重要。</span><span style="background: silver; color: #333333; font-family: SimSun">（</span><strong><span style="background: silver; color: red; font-family: SimSun">按照劳动法</span></strong><strong><span style="background: silver; color: red">42</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">条，不得解除三期【孕期、产期、哺乳期】妇女。那么如果一定要违反劳动法解除劳动关系，只能按照违反劳动法，按照第八十七条进行二倍赔偿，也就是</span></strong><strong><span style="background: silver; color: red">3</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">倍）</span></strong></p>
<p style="margin-left: 9pt"><strong><span style="font-size: 13.5pt; color: #333333; font-family: 'ＭＳ 明朝'">案例</span></strong><strong><span style="font-size: 13.5pt; color: #333333">:</span></strong></p>
<p style="margin-left: 9pt"><strong><span style="font-size: 13.5pt; color: #333333"><a href="http://www.tianya.cn/publicforum/content/law/1/119373.shtml">http://www.tianya.cn/publicforum/content/law/1/119373.shtml</a> </span></strong></p>
<p style="margin-left: 9pt"><span style="background: silver; font-family: 'ＭＳ 明朝'">案情：</span><span style="background: silver">A</span><span style="background: silver; font-family: 'ＭＳ 明朝'">公司辞退</span><span style="background: silver">B</span><span style="background: silver; font-family: 'ＭＳ 明朝'">孕</span><span style="background: silver; font-family: SimSun">妇</span><span style="background: silver; font-family: 'ＭＳ 明朝'">（不考</span><span style="background: silver; font-family: SimSun">虑</span><span style="background: silver">B</span><span style="background: silver; font-family: 'ＭＳ 明朝'">可能存在的</span><span style="background: silver; font-family: SimSun">过错</span><span style="background: silver; font-family: 'ＭＳ 明朝'">，假</span><span style="background: silver; font-family: SimSun">设</span><span style="background: silver">A</span><span style="background: silver; font-family: 'ＭＳ 明朝'">毫无道理毫无依据的辞退</span><span style="background: silver">B</span><span style="background: silver; font-family: 'ＭＳ 明朝'">孕</span><span style="background: silver; font-family: SimSun">妇</span><span style="background: silver; font-family: 'ＭＳ 明朝'">）。</span></p>
<p style="margin-left: 9pt"><span style="background: silver; font-family: 'ＭＳ 明朝'">　　</span><span style="background: silver; font-family: 'ＭＳ 明朝'">一</span><span style="background: silver; font-family: SimSun">审结</span><span style="background: silver; font-family: 'ＭＳ 明朝'">果：<strong><span style="color: red">判</span></strong></span><strong><span style="background: silver; color: red; font-family: SimSun">赔</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">全</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">额</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">孕期工</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">资</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">、全</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">额产</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">期（</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">晚</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">育</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">还</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">加了</span></strong><strong><span style="background: silver; color: red">15</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">天）工</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">资</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">、</span></strong><strong><span style="background: silver; color: red">75%</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">的哺乳期工</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">资</span></strong><span style="background: silver; font-family: 'ＭＳ 明朝'">，并以入</span><span style="background: silver; font-family: SimSun">职时间</span><span style="background: silver; font-family: 'ＭＳ 明朝'">至三期届</span><span style="background: silver; font-family: SimSun">满为劳动</span><span style="background: silver; font-family: 'ＭＳ 明朝'">合同</span><span style="background: silver; font-family: SimSun">关</span><span style="background: silver; font-family: 'ＭＳ 明朝'">系存</span><span style="background: silver; font-family: SimSun">续</span><span style="background: silver; font-family: 'ＭＳ 明朝'">期</span><span style="background: silver; font-family: SimSun">间计</span><span style="background: silver; font-family: 'ＭＳ 明朝'">算在</span><span style="background: silver; font-family: SimSun">职时间</span><span style="background: silver; font-family: 'ＭＳ 明朝'">，然后以</span><span style="background: silver; font-family: SimSun">该</span><span style="background: silver; font-family: 'ＭＳ 明朝'">在</span><span style="background: silver; font-family: SimSun">职时间</span><span style="background: silver; font-family: 'ＭＳ 明朝'">按照《</span><span style="background: silver; font-family: SimSun">劳动</span><span style="background: silver; font-family: 'ＭＳ 明朝'">合同法》第八十七条判</span><span style="background: silver; font-family: SimSun">赔</span><span style="background: silver; font-family: 'ＭＳ 明朝'">了</span><strong><span style="background: silver; color: red; font-family: SimSun">赔偿</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">金（即合法解除的</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">补偿</span></strong><strong><span style="background: silver; color: red; font-family: 'ＭＳ 明朝'">金的双倍）</span></strong><span style="background: silver; font-family: 'ＭＳ 明朝'">。一</span><span style="background: silver; font-family: SimSun">审</span><span style="background: silver; font-family: 'ＭＳ 明朝'">不是我代理的。</span></p>
<p style="margin-left: 9pt"><span style="background: silver; font-family: 'ＭＳ 明朝'">　　</span><span style="background: silver; font-family: 'ＭＳ 明朝'">二</span><span style="background: silver; font-family: SimSun">审</span><span style="background: silver">A</span><span style="background: silver; font-family: 'ＭＳ 明朝'">公司找到我，我想当然的以</span><span style="background: silver; font-family: SimSun">为</span><span style="background: silver; font-family: 'ＭＳ 明朝'">，按照《</span><span style="background: silver; font-family: SimSun">劳动</span><span style="background: silver; font-family: 'ＭＳ 明朝'">合同法》第八十七条的</span><span style="background: silver; font-family: SimSun">规</span><span style="background: silver; font-family: 'ＭＳ 明朝'">定，</span><span style="background: silver; font-family: SimSun">劳动</span><span style="background: silver; font-family: 'ＭＳ 明朝'">者可以</span><span style="background: silver; font-family: SimSun">选择</span><span style="background: silver; font-family: 'ＭＳ 明朝'">要求</span><span style="background: silver; font-family: SimSun">继续</span><span style="background: silver; font-family: 'ＭＳ 明朝'">履行，不要求</span><span style="background: silver; font-family: SimSun">继续</span><span style="background: silver; font-family: 'ＭＳ 明朝'">履行的，</span><span style="background: silver; font-family: SimSun">应</span><span style="background: silver; font-family: 'ＭＳ 明朝'">当</span><span style="background: silver; font-family: SimSun">仅</span><span style="background: silver; font-family: 'ＭＳ 明朝'">支付双倍</span><span style="background: silver; font-family: SimSun">补偿</span><span style="background: silver; font-family: 'ＭＳ 明朝'">即可，一</span><span style="background: silver; font-family: SimSun">审</span><span style="background: silver; font-family: 'ＭＳ 明朝'">判决属适用法律</span><span style="background: silver; font-family: SimSun">错误</span><span style="background: silver; font-family: 'ＭＳ 明朝'">。</span></p>
<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/315853.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> 2010-03-19 00:27 <a href="http://www.blogjava.net/jinfeng_wang/archive/2010/03/19/315853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><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>17</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>1</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，$/Application/Docs，而 Docs工程下的内容可能对你没有任何用处。当你每次从$/Application处进行Get操作后，都需要从本地删除多余的Docs目录。此时可以对Docs 进行Cloak操作。这样，每次的Get操作将只把Code和Test下的内容放到本地。如果你需要获取Docs工程下的内容，则可以单独从Docs处进行Get 操作。</p><p class="middletitle"><a name="43"><strong>4.3 Branch、Share、Label和Pin操作(Branch、Share、Label and Pin)</strong></a></p><p class="middletitle"><a name="431"><strong>4.3.1 对文件和工程的Branch/Share操作(Branch and Share Files and Projects) *</strong></a></p><p>　　在VSS中，通过Share操作，一个文件可以被多个工程共享，在任何一个工程中对该文件的更改，都将反映到其他相关工程里。</p><p>　　Branch操作则消除这种共享，每次将一个被共享的文件拆成两个分支，在不同工程中分别跟踪该文件。通过查看文件属性的Links属性页可以了解该文件被哪些工程共享，通过查看Paths属性页可以了解文件的分支状况。</p><p>　　例如：产品目前的正式版本为2.0（工程路径为$/Application），在加入新功能后将升级为3.0。但在开始升级的过程中，其间的一个过渡版本2.1存在bug，需要修改。此时可以进行如下操作：选择被Label标识为2.0的那个版本（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#432"><font color="#000080"><u>给文件、工程指定标签</u></font></a>），利用Share功能创建过渡版本（工程路径为$/Application2.1），此时两个工程中的文件是共享的，且$/Application2.1中的所有文件都处于Pin状态（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#433"><font color="#000080"><u> Pin操作） </u></font></a>，即：在向3.0升级的过程中，对$/Application中相关文件的更改，将不影响$/Application2.1下的内容，但此时文件仍是共享的。仅对需要修改bug的文件采取Branch操作。这样做的好处是，中间版本的bug修改工作和3.0的升级工作可以同时进行，并且最大限度的降低了所需的存储空间。</p><p class="middletitle"><a name="432"><strong><font color="#223355">4.3.2 给文件、工程指定标签(Label Files and Projects) *</font></strong></a></p><p>　　VSS使用3种方式跟踪文件的历史记录：内部版本号，日期，用户自定义标签。</p><p>　　标签可以是一个不超过31个字符长度的串，例如："1.0"、"2.01b"、"Final Beta"、"Approved for QA"。应用Label功能，用户就可以获取某个特定时期的软件内容了。所有当前工程下的文件和子工程都将继承该标签。</p><p>　　注意下面几点： 
</p><ul><li>当使用Label功能时，表明你在所选工程的历史记录里创建了一个新的版本，但文件和工程本身的内容并未发生变化。 
</li><li>对某个工程的某个标签再次使用Label操作将覆盖原来的标签内容。 </li></ul><p></p><p>　　请参见附录A1：<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#a1"><font color="#000080"><u>同时维护一个工程的多个版本</u></font></a></p><p class="middletitle"><a name="433"><strong><font color="#223355">4.3.3 Pin操作(Pin)*</font></strong></a></p><p>　　该功能对共享文件很有用，尽管它的使用不仅限于共享文件，也包括其他任何文件。当你对一个文件实施Pin操作后，你将不能对之做任何修改。如果一个文件在Pin之后又被实施了Share操作，而被Pin的那个版本同时也是被共享的版本，则所有共享该文件的工程都不能更改该文件。如果一个文件先被实施了Share操作，而后在某个工程中被Pin了，则除了这个工程外的其余工程仍可以更改该文件（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#431"><font color="#000080"><u>对文件和工程的Branch/Share操作</u></font></a>）。<br /></p><p class="middletitle"><a name="44"><strong><font color="#223355">4.4 其他操作(Other Use)</font></strong></a></p><p class="middletitle"><a name="441"><strong>4.4.1 扩展关键字(Expand Keywords)*</strong></a></p><p>　　VSS可以将某些指定信息（例如：VSS内部版本号）直接插入文本文件中。用户只要将某些关键字放入文件的注释中，每次添加（Add）或签入（Check In）文件时，VSS都会自动查找这些关键字，并将相关信息置于其后。</p><p>　　VSS中常用的关键字： 
</p><table border="1"><tbody><tr><td>关键字</td><td>描述</td></tr><tr><td>$Archive: $</td><td>文件在VSS中的路径名</td></tr><tr><td>$Author: $</td><td>最近一次更改文件的用户</td></tr><tr><td>$Date: $</td><td>最近一次签入的时间</td></tr><tr><td>$History: $</td><td>文件的历史记录</td></tr><tr><td>$Revision: $</td><td>VSS内部版本号</td></tr><tr><td>$NoKeywords: $</td><td>使VSS对其后的所有关键字不进行扩展</td></tr></tbody></table><p>　　例如：</p><p>　　在某文件中加入如下一行：</p><p>　　$Revision: $</p><p>　　若当前该文件在VSS内部的版本号是22，则签入后VSS会将之修改为：</p><p>　　$Revision: 23 $</p><p class="middletitle"><a name="442"><strong>4.4.2 使用Shadow目录(Work with Shadow Folders)*</strong></a></p><p>　　Shadow目录位于服务器端，包含了工程中所有的文件。这些文件既非位于VSS数据库中的master copy，亦非位于本地工作目录的local copy，而是最近一次签入的所有内容。Shadow目录应该由管理员来设置。</p><p>　　是否使用Shadow目录功能是可选的，通常在如下两种情况下可以考虑使用该功能： 
</p><ul><li>为使某些用户能查看文件（但不能更改），这些用户可能没有对VSS的访问权限。 
</li><li>不让你的本地工作目录保留可编译的软件副本。为使每个用户都能得到一个最新版本的软件，所有用户可能希望在某个目录下集中进行编译，而非在各自的工作目录下编译。在这种情况下，Shadow目录功能通常和添加（Add）、签入（Check In）之后的Remove Local Copy结合使用。 </li></ul><p></p><p>　　Shadow目录不会跟踪子工程的变化，例如：你有一个被Shadow的工程$/A，包含两个子工程：$/A/1和$/A/2，而你又将$/A/2重命名为 $/A/B，这种变化将不会被反映到Shadow目录中。你可以手工修改，或者利用Reconcile All功能，使之保持同步。</p><p class="middletitle"><a name="443"><strong>4.4.3 性能优化(Optimize Performance)*</strong></a></p><p>　　有两种方法可以改善VSS的性能：尽可能多的将内容通过网络拷贝至本地来做；修改初始化文件对VSS的性能进行微调。</p><p>　　具体优化措施： 
</p><ul><li>在SS.INI或SRCSAFE.INI文件中设置如下变量： 
<p>Diff_Ignore (PC) = c-e-s-w-</p><p>使VSS在进行文件比较时忽略end-of-line标记，从而加快运行效率</p><p>CP_OnSelection = No</p><p>在使用VSS Explorer时，缺省状态下，用户使用鼠标单击或使用键盘的方向键在工程列表上移动时，就会选中工程。设为No后，只有双击鼠标或按回车键才会选中。</p></li><li>设置临时目录 
<p>缺省情况下，VSS将临时文件存于服务器端，但管理员可以通过修改SS.INI中的Temp_Path变量，将临时路径设置在本地。</p></li><li>让管理员在SRCSAFE.INI文件中将Lock_Mode变量设置为Native 
<p>这是SRCSAFE.INI中该变量的缺省设置，把该变量设置为Native将使几乎所有的VSS操作都得到加速。该变量只能由管理员来设置。</p></li><li>管理员通过Disable下面的功能，也可以一定程度地改善性能： 
<ul><li>Shadow folders（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#442"><font color="#000080"><u>使用Shadow目录</u></font></a>） 
</li><li>Journal files 
</li><li>Project security system（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#332"><font color="#223355"><u>安全访问权限</u></font></a>） 
</li><li>Keyword expansion（参见<a href="http://apple.upc.edu.cn/Article/ShowArticle.asp?ArticleID=280#441"><font color="#223355"><u>扩展关键字</u></font></a>） </li></ul></li></ul><p></p><p class="middletitle"><a name="444"><strong><font color="#223355">4.4.4 查找文件(Search for Files)</font></strong></a></p><p>　　VSS Explore的list view缺省时只显示当前工程中的所有文件。通过使用Search命令，可以只显示符合指定要求的文件。例如：只显示 .h文件，只现实被签出的文件。Search命令是允许递归的。</p><p class="middletitle"><a name="445"><strong>4.4.5 设置密码(Set Passwords)</strong></a></p><p>　　如果VSS管理员指定域账号为VSS登录账号，则用户登录VSS时将不会提示输入密码。</p><p class="middletitle"><a name="446"><strong>4.4.6 编写批处理文件(Writing Batch Files)*</strong></a></p><p>　　在编写批处理文件时，一些在命令行方式下使用的交互手段需要改变。</p><p></p><ul><li>屏蔽输入（Disable Input） 
<p>如果你的批处理文件中包含了一系列VSS命令（它们可能需要整夜运行），你一定不希望程序执行期间会停下来提示用户输入信息。有3个命令行选项可以解决此类问题。</p><p>缺省时，VSS在执行诸如添加（Add）、签入（Check In）等操作时会提示你输入注释（Comment），利用-c选项可以避免该类提示： 
</p><table border="1"><tbody><tr><td>命令</td><td>描述</td></tr><tr><td>-c-</td><td>不添加注释</td></tr><tr><td>"-cHello"</td><td>使用Hello字串作为注释</td></tr><tr><td>-c@COMMENT.TXT</td><td>使用comment.txt文件的内容作为注释</td></tr></tbody></table><p>此外，VSS通常会要求用户回答yes或no，你可以使用-i选项避免此类问题： 
</p><table border="1"><tbody><tr><td>命令</td><td>描述</td></tr><tr><td>-i-y</td><td>对所有此类提问自动回答Yes</td></tr><tr><td>-i-n</td><td>对所有此类提问自动回答No</td></tr><tr><td>-i</td><td>使用缺省回答</td></tr></tbody></table><p>VSS也可能会提示登录名，你可以使用-y选项提供足够多的信息。</p></li><li>重定向输出 
<p>缺省时，VSS将所有输出定向到屏幕，在命令行状态下你可以使用-o选项分页输出，而在批处理文件中你同样可以利用-o屏蔽输出或重定向输出。 
</p><table border="1"><tbody><tr><td>命令</td><td>描述</td></tr><tr><td>-o-</td><td>屏蔽输出</td></tr><tr><td>-oRESULTS.TXT</td><td>重定向所有输出到文本文件results.txt中，如果该文件已存在，输出内容将追加到该文件末尾。</td></tr></tbody></table></li><li>使用命令行返回值 
<p>在命令行状态下运行VSS时，VSS会设置一些返回值来标明运行状态。你可以在批处理文件中根据VSS的返回值采取相应措施。 
</p><table border="1"><tbody><tr><td>返回值</td><td>描述</td></tr><tr><td>100</td><td>表明出错，例如：VSS无法找到数据库文件，或者你试图签出某个早已被签出的文件。</td></tr><tr><td>1</td><td>表明一个不是很严重的错误，将在如下三种情况下发生：<br />当你使用ss Dir时，没有找到任何条目。<br />当你使用ss Status时，至少有一项被签出。<br />当你使用ss Diff时，至少有一个文件不一致。<br />所有这些情况表明，即使本次操作是成功的，你执行的下一个VSS命令也可能操作失败。</td></tr><tr><td>0</td><td>VSS成功执行。</td></tr></tbody></table></li></ul><p></p><p class="middletitle"><a name="447"><strong>4.4.7 定制SS.INI和SRCSAFE.INI文件(Customize the SS.INI and SRCSAFE.INI Files) </strong></a></p><p>　　VSS有两类初始化文件，它们包含了VSS的一些环境变量：SS.INI，每个用户都有一个这样的文件；SRCSAFE.INI，仅有一个，定义了VSS 的一些全局变量，只有管理员才有权修改它。</p><p class="middletitle"><a name="a"><font color="#421ae6"><strong>附录</strong></font></a><font color="#421ae6"><strong> </strong></font><a name="a1"><font color="#421ae6"><strong> 同时维护一个工程的多个版本(Maintain Multiple Versions of a Project)</strong></font></a></p><p>　　你可以使用Share/Pin/Branch的方式，也可以使用Label方式。如果你所处的环境只要求少量的改动，比如：轻量级的patch，使用 Label比较合适；如果你正在规划大量的开发内容，使用Share/Pin/Branch比较合适。例如：在软件处于Beta版时，你可以通过Label功能冻结（freeze）之，并同时修改Beta版的bug。当你正同时维护着某个产品的1.1版和2.0版时，合理的做法是，为每个版本创建一个新的工程， Share并Pin所有的文件，在需要的时候Branch。当1.1发布时，你可以将1.1版的工程Label，而后将对1.1版的改动重新Merge到2.0版中。下面的几个场景为你使用Label功能提供指导：</p><p><b>场景1：理想情况</b></p><p>1、对即将到达Beta 1版的工程进行开发和测试。<br />2、当你认为时机适宜时，将之Label为"Beta 1"。<br />3、开始Beta 2版的工作。 </p><p><b>场景2：文件A的某个版本被错误地包含在Beta 1版中</b></p><p>1、对即将到达Beta 1版的工程进行开发和测试。<br />2、当你认为时机适宜时，将之Label为"Beta 1"。<br />3、开始Beta 2版的工作。 <br />4、如果发现文件A某一时期的版本被错误的包含在了Beta 1版中，选择该文件的正确版本并Label为"Beta 1"。<br />5、获取（Get）Beta 1 版的工程。 </p><p><b>场景3：需将bug-fix后的文件A被包含在Beta 1版中，而其余文件未曾改动</b></p><p>1、对即将到达Beta 1版的工程进行开发和测试。<br />2、当你认为时机适宜时，将之Label为"Beta 1"。<br />3、开始Beta 2版的工作。 <br />4、你发现，包含在Beta 1版中文件A的那个版本存在bug，必须改正，而工程中的其余文件则不须改动。<br />5、签出该文件，改正，然后签入。<br />6、将工程重新Lable为"Beta 1"（你将被询问是否确认删除原有标记）。 </p><p><b>场景4：需将bug-fix后的文件A包含在Beta 1版中，而其余文件也作了改动</b></p><p>1、对即将到达Beta 1版的工程进行开发和测试。<br />2、当你认为时机适宜时，将之Label为"Beta 1"。<br />3、开始Beta 2版的工作。 <br />4、你发现，包含在Beta 1版中文件A的那个版本存在bug，必须改正，而工程中的其余文件已经改动过且已经被签入。<br />5、签出该文件，改正，然后签入（此时该文件的VSS内部版本号将自动加1）。<br />6、将该文件Label为"Beta 1"（和工程的Label同名），这将使该文件的现有版本被指定为"Beta 1"。 </p><p><b>场景5：文件A的一个原有版本需要进行bug-fix，并加入Beta 1版中</b></p><p>1、对即将到达Beta 1版的工程进行开发和测试。<br />2、当你认为时机适宜时，将之Label为"Beta 1"。<br />3、开始Beta 2版的工作。 <br />4、你发现，包含在Beta 1版中文件A的那个版本存在bug，必须改正。例如：文件的当前内部版本号是6，且包含了为达到Beta 2版所做的某些改动，而你不希望将这些改动并入Beta 1版中。<br />5、签出文件A（Version 6）<br />6、获取Version 4，覆盖Version 6的本地版本。 <br />7、修改该文件Beta 1版中的bug，然后签入。这将使文件A的内部版本号升至7（Version 4的内容加上bug-fix后的内容，但没有包含 Version 5和Version 6的内容）<br />8、将Version 7 Label为"Beta 1"。这将使文件A的Version 7版被指定为"Beta 1"。现在，如果你尝试获取Beta 1版的工程时，你将会得到包含bug-fix后的文件A（被单独Label）连同原来Label为"Beta 1"的工程中的其余文件。<br />9、为了继续 Beta 2版的工作，需要恢复在Version 5和Version 6上的改动，再次签出文件A（Version 7）<br />10、获取Version 6。<br />11、覆盖Version 7的本地版本，或合并之（这将使本地版本变成Version 6的内容加上你在Version 7中为"Beta 1"所做的bug-fix）。<br />12、继续修改文件A的本地版本直到你满意，然后签入。这将产生文件A的Version 8，现在你将可以继续Beta 2版的工作了。<br /></p><p class="middletitle"><a name="a2"><b><font color="#223355">附表 VSS中部分命令的对应权限级别</font></b></a></p><p>下表中打星号表示具有该类权限的用户可以使用该命令。 
</p><table border="1"><tbody><tr align="middle"><td align="middle"><b>功能</b></td><td align="middle" width="50"><b>R</b></td><td align="middle" width="50"><b>C</b></td><td align="middle" width="50"><b>A</b></td><td align="middle" width="50"><b>D</b></td></tr><tr><td align="middle">Add</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Branch</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Check In</td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Check Out</td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Cloak</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Create [1]</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Delete</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Destroy</td><td align="middle"> </td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td></tr><tr><td align="middle">Difference</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Get Latest Version</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">History</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Label</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Links</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Merge [2]</td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Merge</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Move [3]</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Move</td><td align="middle"> </td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td></tr><tr><td align="middle">Pin</td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Purge</td><td align="middle"> </td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td></tr><tr><td align="middle">Recover</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Rename</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Rollback</td><td align="middle"> </td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td></tr><tr><td align="middle">Share [4]</td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Share</td><td align="middle"> </td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Undo Check Out</td><td align="middle"> </td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr><tr><td align="middle">Set Working Folder</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td><td align="middle">*</td></tr></tbody></table><p>[1] 此处指用户必须有对Parent Project的A类权限。<br />[2] 此处指用户必须有对目的Project的C类权限，同时有对原Project的R类权限。<br />[3] 此处指用户必须有对目的Parent Project的A类权限，同时有对原Parent Project的D类权限。<br />[4] 此处指用户必须有对原 Project的C类权限，同时有对目的Project的A类权限。 </p><p class="middletitle"><font color="#0099ff">如需复制、传播，请附上本声明，谢谢。原文出处：http://morningspace.51.net/， moyingzz@etang.com</font><a name="a1"></a></p><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/97939.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-02-05 10:57 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/02/05/97939.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>郑重推荐一款软件： http tunnel</title><link>http://www.blogjava.net/jinfeng_wang/archive/2006/01/04/26616.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Wed, 04 Jan 2006 14:29:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2006/01/04/26616.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/26616.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2006/01/04/26616.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/26616.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/26616.html</trackback:ping><description><![CDATA[<SPAN class=db>软件介绍：</SPAN><SPAN class=pt> 现在有很多公司都为自己的网络加装了防火墙，虽然防火墙主要是为了抵抗外敌，但很多公司也拿防火墙阻止员工任意使用 Internet。如果你有某个位于 Internet 的服务是公司政策所不允许的，你会就此放弃吗？别担心，防火墙所挡住的，HTTP-Tunnel NG 现在还给你</SPAN><BR><BR><BR><A href="http://www.http-tunnel.com/html/"><BR>http://www.http-tunnel.com/html/</A><BR><BR><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/26616.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> 2006-01-04 22:29 <a href="http://www.blogjava.net/jinfeng_wang/archive/2006/01/04/26616.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>some words from csdn (ZZ)</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/06/17/6272.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Fri, 17 Jun 2005 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/06/17/6272.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/6272.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/06/17/6272.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/6272.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/6272.html</trackback:ping><description><![CDATA[1) Improve your math skill.<BR>&nbsp;2) Improve your English skill.<BR>&nbsp;3) Improve your computer science skill.<BR>&nbsp;4) Improve your communication skill.<BR>&nbsp;5) Remove BS from your vocabulary, learn from everyone, as long as they have one thing stronger than you.<BR>&nbsp;6) Try define every vague term you're using precisely.<BR>&nbsp;7) Do not stop at surface, think deeper, dig deeper.<BR>&nbsp;8) Do not stop at surface, think higher, look at bigger picture.<BR>&nbsp;9) Be the best at your current job, learn something new, and then try to get a better job.<BR>10) Help people less experienced than you.<BR>11) Believe you can be&nbsp;expert too, reward yourself for your progress, even if it's small.<BR>12) Do something grand with your life, realize your childhood dream.<BR>13) Enjoy life.<BR>14) Pass it to your kids.<BR><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/6272.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> 2005-06-17 11:51 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/06/17/6272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>小记一则</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/04/25/3731.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Mon, 25 Apr 2005 09:08:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/04/25/3731.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/3731.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/04/25/3731.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/3731.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/3731.html</trackback:ping><description><![CDATA[<P>&nbsp;</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">一切看的淡淡的<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>金钱看的轻轻的<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>目光看的远远的<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>健康看的重重的<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV>.<BR>这四句话，应该是值得记住的，尤其最后一句，切记切记！<img src ="http://www.blogjava.net/jinfeng_wang/aggbug/3731.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> 2005-04-25 17:08 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/04/25/3731.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用JMeter进行性能测试</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/04/19/3463.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Tue, 19 Apr 2005 07:45:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/04/19/3463.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/3463.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/04/19/3463.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/3463.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/3463.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java">http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java</A><BR><BR>注： <SPAN class=atitle>可以对下面的文件进行改写，形成测试程序，供JMmeter测试调用。<BR>jakarta-jmeter-2.0.3\src\protocol\java\org\apache\jmeter\protocol\java\test\JavaTest.java<BR><BR>改写后的内容必须打包，放到jmeter的lib目录。<BR><BR><BR><BR><BR>使用JMeter进行性能测试</SPAN></TD>
<TD width=8><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></TD>
<TD align=right width=180><NOBR>
<TABLE cellSpacing=0 cellPadding=0>
<TBODY>
<TR vAlign=top>
<TD align=right></TD>
<TD width=46>
<FORM action=https://www-130.ibm.com/developerworks/secure/email-it.jsp>&nbsp;</FORM></TD></TR></TBODY></TABLE></NOBR><BR><BR></TD>
<TD width=6><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=6 border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#000000 colSpan=5><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=100 border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#ffffff colSpan=5><IMG height=8 alt="" src="http://www.ibm.com/i/c.gif" width=100 border=0></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width=5><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=5 border=0></TD>
<TD width="100%">
<TABLE cellSpacing=0 cellPadding=0 width=168 align=right border=0>
<TBODY>
<TR>
<TD width=8><IMG height=21 alt="" src="http://www.ibm.com/i/c.gif" width=5></TD>
<TD width=160>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>内容：</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#1">JMeter作用领域</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#2">使用JMeter测试Web应用</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#3">总结</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#4">工具下载：</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR><!--Standard links for every dw-article-->
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#resources">参考资料 </A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#author1">关于作者</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#rating">对本文的评价</A></TD></TR>
<TR>
<TD><IMG height=10 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>订阅:</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=1 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www-128.ibm.com/developerworks/cn/newsletter/">developerWorks 时事通讯</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=150 bgColor=#000000 colSpan=2 height=2><IMG height=2 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR>
<TR>
<TD width=150 bgColor=#ffffff colSpan=2 height=2><IMG height=2 alt="" src="http://www.ibm.com/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<P><A href="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/?ca=dwcn-newsletter-java#author1"><NAME>肖菁</NAME></A><BR>软件工程师<BR>2004 年 2 月 13 日</P>
<BLOCKQUOTE>JMeter 是 Apache 组织的开放源代码项目，它是功能和性能测试的工具，100%的用java实现，最新的版本是1.9.1。本文中作者将向大家介绍如何使用 JMeter 进行测试。</BLOCKQUOTE>
<P>JMeter是Apache组织的开放源代码项目，它是功能和性能测试的工具，100%的用java实现，最新的版本是1.9.1，大家可以到 <A href="http://jakarta.apache.org/jmeter/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">http://jakarta.apache.org/jmeter/index.html</A>下载源代码和查看相关文档。 </P>
<P><A name=1><SPAN class=atitle2>JMeter作用领域</SPAN></A><BR></P>
<P>JMeter可以用于测试静态或者动态资源的性能（文件、Servlets、Perl脚本、java对象、数据库和查询、ftp服务器或者其他的资源）。JMeter用于模拟在服务器、网络或者其他对象上附加高负载以测试他们提供服务的受压能力，或者分析他们提供的服务在不同负载条件下的总性能情况。你可以用JMeter提供的图形化界面分析性能指标或者在高负载情况下测试服务器/脚本/对象的行为。</P>
<P><A name=2><SPAN class=atitle2>使用JMeter测试Web应用</SPAN></A><BR></P>
<P>接下来的章节里，作者将详细的演示如何使用JMeter来测试Web应用的完整过程。</P>
<P><A name=N1005D><SPAN class=atitle3>2.1 测试环境</SPAN></A><BR></P>
<P>作者使用了Tomcat作为Web服务器进行测试，被测试的内容是一个jsp文件和一个servlet，jsp文件调用JavaBean、打印相关信息，servlet接受用户参数、调用javabean、输出相关信息。详细的内容请参考作者提供的JMeter.war的内容。</P>
<P><A name=N10068><SPAN class=atitle3>2.2 安装启动JMeter</SPAN></A><BR></P>
<P>大家可以到通过http://apache.linuxforum.net/dist/jakarta/jmeter/binaries/jakarta-jmeter-1.9.1.zip下载JMeter的release版本，然后将下载的.zip文件解压缩到C:/JMeter（后面的文章中将使用%JMeter%来引用这个目录）目录下。</P>
<P>现在，请使用%JMeter%/bin下面的jmeter.bat批处理文件来启动JMeter的可视化界面，下面的工作都将在这个可视化界面界面上进行操作。下面的图片是JMeter的可视化界面的屏幕截图。</P>
<P><A name=N10078><B>图一： JMeter打开时的屏幕截图</B></A><BR><IMG height=371 alt="图一： JMeter打开时的屏幕截图" src="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/images/image001.png" width=408 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/"> </P>
<P><A name=N10085><SPAN class=atitle3>2.3 建立测试计划（Test Plan）</SPAN></A><BR></P>
<P>测试计划描述了执行测试过程中JMeter的执行过程和步骤，一个完整的测试计划包括一个或者多个线程组(Thread Groups)、逻辑控制（Logic Controller）、实例产生控制器（Sample Generating Controllers）、侦听器(Listener)、定时器（Timer）、比较（Assertions）、配置元素（Config Elements）。打开JMeter时，它已经建立一个默认的测试计划,一个JMeter应用的实例只能建立或者打开一个测试计划。</P>
<P>现在我们开始填充一个测试计划的内容，这个测试计划向一个jsp文件和一个servlet发出请求，我们需要JMeter模拟五个请求者（也就是五个线程），每个请求者连续请求两次，下面的章节介绍了详细的操作步骤。</P>
<P><A name=N10093><SPAN class=atitle3>2.4 增加负载信息设置</SPAN></A><BR></P>
<P>这一步，我们将向测试计划中增加相关负载设置,是Jmeter知道我们需要模拟五个请求者，每个请求者在测试过程中连续请求两次。详细步骤如下：</P>
<P>1. 选中可视化界面中左边树的Test Plan节点，单击右键，选择Add'Thread Group，界面右边将会出现他的设置信息框。</P>
<P>2. Thread Group有三个和负载信息相关的参数： <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">Number of Threads： 设置发送请求的用户数目 <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">Ramp-up period： 每个请求发生的总时间间隔，单位是秒。比如你的请求数目是5，而这个参数是10，那么每个请求之间的间隔就是10／5，也就是2秒 <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">Loop Count： 请求发生的重复次数，如果选择后面的forever（默认），那么 请求将一直继续，如果不选择forever，而在输入框中输入数字，那么请求将重复 指定的次数，如果输入0，那么请求将执行一次。 </P>
<P>根据我们演示例子的设计，我们应该将Number of Threads设置为5，Ramp-up period设置为0（也就是同时并发请求），不选中forever，在Loop Count后面的输入框中输入2，设置后的屏幕截图如下：</P>
<P><A name=N100AF><B>图二：设置好参数的Thread Group。</B></A><BR><IMG height=218 alt="图二：设置好参数的Thread Group。" src="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/images/image003.png" width=447 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/"> </P>
<P><A name=N100BC><SPAN class=atitle3>2.5 增加默认Http属性（可选）</SPAN></A><BR></P>
<P>实际的测试工作往往是针对同一个服务器上Web应用展开的,所以Jmeter提供了这样一种设置, 在默认Http属性设置需要被测试服务器的相关属性，以后的http请求设置中就可以忽略这些相同参数的设置,减少设置参数录入的时间。</P>
<P>我们这里将采用这种属性。你可以通过下面的步骤来设置默认http属性：</P>
<P>1. 选中可视化界面中左边树的Test Plan节点，单击右键，选择Add'config element'http request defaults，界面右边将会出现他的设置信息框。</P>
<P>2. 默认http属性的主要参数说明如下： <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">protocal：发送测试请求时使用的协议 <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">server name or ip：被测试服务器的ip地址或者名字 <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">path： 默认的起始位置。比如将path设置为／jmeter，那么所有的http请求的url中都将增加／jmeter路径。 <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">port number： 服务器提供服务的端口号 </P>
<P>我们的测试计划将针对本机的Web服务器上的Web应用进行测试，所以protocal应该是http，ip使用localhost，因为这个web应用发布的context路径是／jmeter，所以这里的path设置为／jmeter，因为使用Tomcat服务器，所以port number是8080。设置后的屏幕截图如下：</P>
<P><A name=N100DD><B>图三： 测试计划中使用的默认Http参数</B></A><BR><IMG height=176 alt="图三： 测试计划中使用的默认Http参数" src="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/images/image005.png" width=500 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/"> </P>
<P><A name=N100EA><SPAN class=atitle3>2.6 增加Http请求</SPAN></A><BR></P>
<P>现在我们需要增加http请求了，他也是我们测试的内容主体部分。你可以通过下面的步骤来增加性的http请求：</P>
<P>1. 选中可视化界面中左边树的Thread Group节点，单击右键，选择Add'sampler'http request，界面右边将会出现他的设置信息框。</P>
<P>2. 他的参数和2.5中介绍的http属性差不多，增加的属性中有发送http时方法的选择，你可以选择为get或者post。</P>
<P>我们现在增加两个http 请求，因为我们设置了默认的http属性，所以和默认http属性中相同的属性不再重复设置。设置后的屏幕截图如下：</P>
<P><A name=N10100><B>图四：设置好的jsp测试请求</B></A><BR><IMG height=362 alt=图四：设置好的jsp测试请求 src="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/images/image007.png" width=506 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/"> </P>
<P><A name=N1010F><B>图五：设置好的Servlet测试请求（带参数）</B></A><BR><IMG height=364 alt=图五：设置好的Servlet测试请求（带参数） src="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/images/image009.png" width=505 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/"> </P>
<P><A name=N1011C><SPAN class=atitle3>2.7 增加Listener</SPAN></A><BR></P>
<P>增加listener是为了记录测试信息并且可以使用Jmeter提供的可视化界面查看测试结果，里面有好几种结果分析方式可供选择，你可以根据自己习惯的分析方式选择不同的结果显示方式，我们这里使用表格的形式来查看和分析测试结果。你可以通过下面的步骤来增加listener：</P>
<P>1. 选中可视化界面中左边树的Test Plan节点，单击右键，选择Add'listener'view result in table，界面右边将会出现他的设置信息和结果显示框。</P>
<P>2. 你可以设置界面上面的filename属性设置将测试结果保存到某个文件中界面下面将使用表格显示测试结果，表格的第一列sampleno显示请求执行的顺序和编号，url显示请求发送的目标，sample－ms列显示这个请求完成耗费的时间，最后的success列显示改请求是否成功执行。</P>
<P>界面的最下面你还可以看到一些统计信息，最关心的应该是Average吧，也就是相应的平均时间。</P>
<P><A name=N10130><SPAN class=atitle3>2.8 开始执行测试计划</SPAN></A><BR></P>
<P>现在你可以通过单击菜单栏run -&gt; Start开始执行测试计划了。下面这两个图是作者第一次、第二次执行该测试计划的结果图:</P>
<P><A name=N1013D><B>图六：第一次执行后的结果显示</B></A><BR><IMG height=453 alt=图六：第一次执行后的结果显示 src="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/images/image011.png" width=564 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/"> </P>
<P><A name=N1014C><B>图七：第二次执行的结果显示</B></A><BR><IMG height=456 alt=图七：第二次执行的结果显示 src="http://www-128.ibm.com/developerworks/cn/java/l-jmeter/images/image013.png" width=564 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/"> </P>
<P>大家可以看到第一次执行时的几个大时间值均来自于jsp request，这可以通过下面的理由进行解释：jsp执行前都需要被编译成.class文件。所以第二次的结果才是正常的结果。</P>
<P><A name=3><SPAN class=atitle2>总结</SPAN></A><BR></P>
<P>JMeter用于进行供能或者性能测试，通过使用JMeter提供的供能，我们可以可视化的制定测试计划：包括规定使用什么样的负载、测试什么内容、传入的参数，同时，他提供了好多种图形化的测试结果显示方式，使我们能够简单的开始测试工作和分析测试结果。</P>
<P>本文中，作者根据自己的使用经验，详细演示了如何使用JMeter来进行Web测试的全部过程，简单的介绍了JMeter提供测试结果的图形化显示界面中相关参数的含义。希望能够帮助大家学会使用JMeter的基本知识，同时，大家可以参考这个过程和JMeter的帮助文档来实现对java对象、数据库等的测试过程。</P>
<P><A name=4><SPAN class=atitle2>工具下载：</SPAN></A><BR></P>
<P>1. tomcat <A href="http://jakarta.apache.org/tomcat/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">http://jakarta.apache.org/tomcat/index.html</A> </P>
<P>2. JMeter <A href="http://jakarta.apache.org/jmeter/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">http://jakarta.apache.org/jmeter/index.html</A> </P>
<P><A name=resources><SPAN class=atitle2>参考资料 </SPAN></A>
<P>JMeter 的用户指南 ： <A href="http://jakarta.apache.org/jmeter/usermanual/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">http://jakarta.apache.org/jmeter/usermanual/index.html</A> </P>
<P></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><A name=author1></A><SPAN class=atitle2>关于作者</SPAN><BR>姓名: 肖菁， <A href="mailto:jing.xiao@chinacreator.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">jing.xiao@chinacreator.com</A>，作者目前是湖南省长沙铁道学院科创计算机系统集成有限公司软件中心软件工程师，IBM developerworks／BEA dev2dev撰稿人，主要研究J2EE编程技术、Web Service技术以及他们在websphere、weblogic、apache平台上的实现，拥有IBM 的 Developing With Websphere Studio证书。个人网站： <A href="http://vivianj.go.nease.net/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:dw="http://www.ibm.com/developerworks/">vivianj.go.nease.net</A> </TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/3463.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> 2005-04-19 15:45 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/04/19/3463.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>艰苦持久的战争！ ：（</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/04/10/3088.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Sun, 10 Apr 2005 13:01:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/04/10/3088.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/3088.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/04/10/3088.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/3088.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/3088.html</trackback:ping><description><![CDATA[<P>通通通的服务不行了，免费用户基本不稳定了，找了另外一个软件，小声点哦，：）<BR><BR><SPAN class=article_title>使用Http通道突破防火墙限制：</SPAN><BR><A href="http://cj1215.blogchina.com/blog/article_23763.686125.html">http://cj1215.blogchina.com/blog/article_23763.686125.html</A><BR><BR><BR></P><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/3088.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> 2005-04-10 21:01 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/04/10/3088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate's session和《企业应用架构模式》第11章</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/04/05/2869.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Tue, 05 Apr 2005 03:13:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/04/05/2869.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/2869.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/04/05/2869.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/2869.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/2869.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><B><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">hibernate实现了《企业应用架构模式》第11章的许多模式，结合起来则更能理解hibernate的session的作用。只是双方的一些术语未必能直接对应上。<BR>＝＝＝＝＝＝＝＝＝＝＝<BR>Session接口<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">Session（会话）接口是Hibernate应用使用的主要接口。会话接口的实例是轻量级的并且创建与销毁的代价也不昂贵。这很重要因为你的应用可能始终在创建与销毁会话，可能每一次请求都会如此。Hibernate会话并不是线程安全的因此应该被设计为每次只能在一个线程中使用。<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">Hibernate会话是一个介于连接和事务之间的概念。<FONT color=#ff1493>你可以简单地认为会话是对于一个单独的工作单元已装载对象的缓存或集合。Hibernate可以检测到这个工作单元中对象的改变。</FONT>我们有时也将会话称为持续性管理器，因为它也是与持续性有关的操作例如存储和取出对象的接口。注意，Hibernate会话与Web层的HttpSession没有任何关系。当我们在本书中使用会话时，我们指的是Hibernate会话。为了区别，有时我们将HttpSession对象称为用户会话。<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><B><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Arial; mso-font-kerning: 0pt">SessionFactory</SPAN></B><B><SPAN style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Arial; mso-font-kerning: 0pt">接口</SPAN></B><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">应用从</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-bidi-font-size: 9.5pt; mso-bidi-font-family: Arial; mso-font-kerning: 0pt">SessionFactory</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-size: 9.5pt; mso-bidi-font-family: Arial; mso-font-kerning: 0pt">（会话工厂）里获得会话实例。与会话接口相比，这个对象不够令人兴奋。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">&nbsp;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">会话工厂当然不是轻量级的！它打算在多个应用线程间进行共享。典型地，<FONT color=#ff1493>整个应用只有唯一的一个会话工厂——例如在应用初始化时被创建。然而，如果你的应用使用<SPAN lang=EN-US>Hibernate访问多个数据库，你需要对每一个数据库使用一个会话工厂。<o:p></o:p></SPAN></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"><SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN">&nbsp;<o:p></o:p></SPAN></P><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-bidi-font-size: 12.0pt; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-bidi-language: AR-SA">会话工厂缓存了生成的<SPAN lang=EN-US>SQL语句和Hibernate在运行时使用的映射元数据。它也保存了在一个工作单元中读入的数据并且可能在以后的工作单元中被重用（只有类和集合映射指定了这种二级缓存是想要的时才会如此）。<BR><BR><BR></SPAN></SPAN><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/2869.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> 2005-04-05 11:13 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/04/05/2869.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Best practice for risk-free deployment</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/03/30/2600.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Wed, 30 Mar 2005 02:35:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/03/30/2600.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/2600.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/03/30/2600.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/2600.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/2600.html</trackback:ping><description><![CDATA[<H2>Overview</H2>
<P>The cost impact to a company of a failed project can be severe indeed. The impact on the reputation of the project manager can be disastrous.</P>
<P>Software project management is not easy, and it requires considerable skill to successfully manage the many different risks that conspire to de-rail a project:</P>
<P><IMG src="http://www.theserverside.com/articles/content/BuildManagement/IMG01.gif"></P>
<P>Numerous methodologies are available for mitigating these risks – PRINCE2, RUP, DSDN, eXtreme programming – and these have helped to some extent.</P>
<P>This document introduces the 3D™ methodology – a set of best practices and quality tools developed by BuildMonkey, which can be summarised as.</P>
<P><STRONG>De-risk. Deploy. Deliver.</STRONG></P>
<P>In any software project, deployment is a milestone on the project plan that is usually associated with payment – or staged payment. Through the course of development, any number of problems can arise to derail efforts to reach this milestone.</P>
<P>The 3D™ methodology and supporting toolset is based on many years of experience at the sharp end of projects, understanding what has worked and what has not, and the lessons learned from each.</P>
<P>Competent practitioners, and experienced project staff, will find resonance with many of the contents of this document and may find themselves saying “<EM>this is just common sense</EM>”. This is certainly true, but the main problem with common sense is that it is not as common as people think it is.</P>
<P>This document, and the 3D™ methodology, is an attempt to bring that common sense together in a single location, as a coherent set of best practices supported by proven tools to help you to <STRONG><EM>release on-time, on-budget, with no defects</EM></STRONG>.</P>
<H2>The Problem To Be Solved</H2>
<P>No methodology has yet focused on the component that all development projects share – the build.</P>
<P>One of the reasons for this is that the term “build” is interpreted differently by different people:</P>
<UL>
<LI>The development team sees it as compilation and assembly; 
<LI>The integration team see it as the bringing together of all of the components in the application in a format suitable for release; 
<LI>The deployment team see it as something which produces the artifacts that they have to install and configure; 
<LI>The testing team see it as something which produces the artifacts that they have to test; 
<LI>The Project Manager sees it as an opaque step that nobody is entirely responsible for;; 
<LI>The end customer should not see it at all; </LI></UL>
<P>The BuildMonkey view is that the build is the combination of processes and technology that take software from design to deployment – _where the return on investment starts to be seen.</P>
<P>It is clear that a methodology is required to de-risk development projects and to standardise use of the term “Build Management”.</P>
<P><STRONG>Best Practice: “<EM>Build Management</EM>” encompasses everything from compilation, all the way through to release to the customer. </STRONG></P>
<H2>No Release, No Revenue</H2>
<P>Any Finance Director knows that development is just an activity that needs to be tolerated in order to produce something that will deliver a return on investment.</P>
<P>It may sound strange, but a large number of software developers do not appreciate and embrace this basic truth. This is in part due to their closeness to the application being constructed.</P>
<P>A common problem faced by development projects is therefore that it is the software developers who manage the build. This creates a situation where the build is focused on the needs of development, and is not geared towards releasing the output of coding such that business value can be realised.</P>
<P>Build Management should therefore focus on the end result of development – a return on investment – and ensure that all of the inputs to the process are incorporated in pursuit of this goal:</P>
<P>Best Practice: Focus on the end, and accommodate the inputs</P>
<H2>Software Tools Are Only Part of the Answer</H2>
<P>Software projects are a complex set of interdependent people and teams and can be likened to a convoy of ships. A convoy has to move at the rate of the slowest ship. Increasing the speed of a single ship in the convoy will not increase the speed of the convoy – it will simply increase the amount of wasted capacity in the speeded-up ship.</P>
<P>Speeding up the slowest ship will, however, have a positive effect since the whole convoy can now move faster.</P>
<P>Many Project Managers try to improve productivity by implementing some degree of automation in development projects – particularly in the area of the build – and often purchase “<EM>magic bullet</EM>” build software that provides this.</P>
<P>Simply using automated build software does not improve productivity any more than the example above improves convoy speed - as it only increases the speed of a single ship in the convoy.</P>
<P>There is no point in speeding up development, if the target production infrastructure cannot keep pace – this just increases the inefficiency. A lot of organisations make this mistake – highly agile development processes trying to feed into considerably less agile deployment processes. The result is inefficiency, waste and over-run.</P>
<P>Before considering using an automated build tool it is essential to ensure that the inputs to, and outputs from, the build can cope with the improved build speed. It is imperative to ensure that the processes and technology employed are geared towards taking the project to a successful conclusion – on-time and on-budget.</P>
<P>Best Practice: Don’t rely on software tools alone, they may solve symptoms whilst creating problems elsewhere</P>
<H2>Configuration Management Best Practices</H2>
<P>Software Configuration Management (SCM) is a relatively mature discipline with much written about methodologies and techniques, and these will not be recreated here.</P>
<P>We will focus instead on leveraging the SCM repository, and the facilities that it offers, to further the goals of the project rather than to consider SCM in its own right.</P>
<H2>It All Starts Here</H2>
<P>The SCM repository - how it is managed and used – is the keystone of good build management and successful delivery of projects.</P>
<P>The SCM repository is the slave of the project, not the other way round. It should be solid and reliable, yet flexible enough to accommodate the needs of new projects. Project Managers should not have to retrofit their planning to accommodate an inflexible SCM setup.</P>
<P>If used correctly, the SCM repository will enhance productivity, and minimize risk, through being able to provide exactly what the project – and project management – require. If used incorrectly, it can cause delay and slippage through having to do things inefficiently further down the chain.</P>
<P>Best Practice: The SCM repository is the slave of the project, not the other way round.</P>
<H2>Configuration Management is not Version Control</H2>
<P>Most software developers regard the SCM repository as a massive storage area where they simply check versions in and out – a common cause of problems.</P>
<P>Simply checking things into an SCM repository is not Configuration Management any more than karaoke is opera.</P>
<P>A well-maintained SCM repository is so much more than version control, and should provide:</P>
<UL>
<LI>The ability to recreate any identified baseline, at any time; 
<LI>Meaningful statistics on what is changing, when and by whom; 
<LI>Management information, such as “<EM>how many new defects were introduced by the refactoring of component ‘X’?</EM>” </LI></UL>
<P>In order to be truly effective in a project, the SCM repository should store all of the artifacts that form part of a baseline or a release.</P><B>Source Code</B> 
<P>Most development projects simply store the code that is being developed and their use of the SCM repository is no more sophisticated than this.</P><B>Data</B> 
<P>Most applications nowadays are not just source code. Take the example of a modern computer game – the vast majority of the code base is made up of artifacts other than code such as audio clips, pictures and movie clips.</P><B>Database Structure and Contents</B> 
<P>Where an application relies on a database this database will have a schema and structure that may change from release to release – this schema must be captured.</P>
<P>There will normally also be seed data for the database which should be considered as part of the baseline.</P><B>Application Configuration</B> 
<P>In a large distributed application, the software being developed will sit atop a number of pieces of software (e.g. application servers, web servers and message queues).</P>
<P>The configuration of these underlying applications have an effect on the quality – or otherwise – of the software being developed and should, therefore, be considered part of the baseline for a release.</P><B>Environment Configuration</B> 
<P>The underlying environment and infrastructure is a key component of the project, particularly in the case of distributed applications.</P>
<P>Such banal considerations as DNS zone files, user account information and system parameters have to be considered as some of the moving parts which affect the application and therefore be placed under configuration control.</P>
<P>This is of particular importance when there is more than one environment involved in the project (e.g. a development environment and a separate test environment) since the question of “<EM>are these environments the same?</EM>” crops up again and again.</P>
<P>Best Practice: Everything that can be changed, and affect the behaviour of the application, is a candidate for configuration control</P>
<H2>The Point of Labelling</H2>
<P>It is a common misconception that simply applying labels, or tags, to the SCM repository creates a baseline but this is only partly true without corresponding records of:</P>
<UL>
<LI>What label has been applied; 
<LI>When that label has been applied; 
<LI>Why it has been applied (i.e. what milestone, or other external event, the label is associated with); </LI></UL>
<P>The use of a naming convention for labels can deceive even further. For example, a project that uses a date-based labeling convention (<EM>dd_mm_yyyy</EM>) will have several labels of the form (<EM>03_05_2004</EM>, or <EM>09_06_2004</EM>) and will reasonably assume that they have some kind of record of the baseline on those dates.</P>
<P>But what was happening in the project on those dates? Was the <EM>03_05_2004</EM> label applied immediately before a release to test, or immediately after?</P>
<P>Best Practice: Labels should be used to identify and inform about events in the project</P><B>Don’t Label If There Is No Point</B> 
<P>This may seem like stating the obvious, but there should be a reason for a label being applied – the whole purpose of labeling is to identify some event in the development cycle that may need to be re-visited.</P>
<P>To this end, labels can be divided into two categories:</P>
<UL>
<LI>Point-in-time<BR>Associates particular versions with a particular calendar date, or other event that is fixed in time (e.g. <EM>MONTH_END_JAN_2004</EM>, or <EM>RELEASE_1_0_1</EM>); 
<LI>Point-in-process<BR>Associates particular versions with events in the project that may recur at a later stage (e.g. <EM>LATEST_RELEASE</EM>, or <EM>CURRENTLY_IN_UAT</EM>); </LI></UL>
<P>Best Practice: Every label should have a point, whether point-in-time or point-in-process</P>
<H2>Management Information</H2>
<P>The job of the Project Manager, ultimately, is to bring the project to a successful conclusion. If this were an easy task that happened by default, then there would be no need for a Project Manager.</P>
<P>In order to be able to do this job well, a Project Manager needs information. He needs to know what is going on in the project – who is doing what, who is working on which components, and a wealth of information can be obtained from a well-managed SCM repository:</P>
<UL>
<LI>What is changing in the environment – what has changed since a given point in time or how often particular elements are changing; 
<LI>Who is changing things in the environment; 
<LI>Why things are changing in the environment; </LI></UL>
<P>Of course, the final item in the list requires that committers are using descriptive comments to indicate why they are marking a particular change. A well-managed SCM repository should enforce this.</P>
<P>Best Practice: The SCM repository should provide meaningful, and accessible, management information</P>
<H2>Build Best Practices</H2>
<P>As explained at the beginning of this document, the term “build” means different things to different people. The most common interpretation is the one used by developers, where the term “build” describes the compilation and assembly step of their development activities but this narrow interpretation is a common cause of problems and over-runs, on development projects.</P>
<H2>Building is not Compiling</H2>
<P>At the outset of the project, the Project Manager will ask the question “<EM>how long to set up the build?</EM>” and a developer – thinking of compilation and assembly – will answer something like “<EM>1 day”</EM> – a task and duration which is then duly marked on the project plan and development begins.</P>
<P>Later in the project, when it is time to start deploying and testing the application, this “build” needs to be refactored to accommodate the deployment and test tasks. In doing so, it turns out that the way the application is being assembled is not conducive to it being deployed or tested correctly – so the compilation and assembly staged need to be refactored as well.</P>
<P>In the meantime, the development team sits on its hands whilst the “build” is refactored to accommodate the needs of the project – valuable time is lost whilst the deadline continues to advance.</P>
<P>Best Practice: Know what will be required of the build before starting to write the scripts</P>
<H2>Don’t Throw Out The Baby With The Bathwater</H2>
<P>From a build perspective, projects with similar architecture (both in terms of the team and the application) will have similar attributes. There will obviously be some changes required, but these will tend to follow the 80/20 rule to a large degree.</P>
<P>For example, a web application that is being developed by an in-house team and that will be deployed to a Tomcat servlet container and Oracle database will follow largely the same steps and require largely the same deployable artifacts.</P>
<P>A good SCM repository will enable the latest versions of boiler-plate build scripts for such an application to be found. These can be used almost off-the-shelf – meaning that development can start apace without having to wait on the build to be constructed for similar applications .</P>
<P>Best Practice: Well-crafted builds are re-usable and should be re-used</P>
<H2>The Architecture Drives The Build&lt;</H2>
<P>Following on from the previous section, it should be clear that the architecture of what is being developed – and the structure of the team(s) developing it – will dictate how the build should look.</P>
<P>There is little value to be gained in trying to retrofit build scripts for a computer game (developed by 12 people all in the same room) into a project to produce a large J2EE application with development occurring at six different sites around the world.</P>
<P>Best Practice: Well-crafted builds are flexible, but a “one-size-fits-all” approach can be costly</P>
<H2>Management Information</H2>
<P>There are a number of people who need information that the build can provide:</P>
<UL>
<LI>The Project Manager needs to track overall progress against defined milestones – number of outstanding defects, whether a committed release date will be met etc; 
<LI>Development leads need to be sure that the code is of the quality that they require – test reports, bug analysis patterns, code metrics, document and UML generation etc; 
<LI>The deployment team need to know that the artifacts will work in their target environment, and that the environment is as the application expects it to be. They also need to know whether two (or more) environments are “<EM>the same</EM>”; 
<LI>The test team need to have confidence that they are testing against a known baseline, and whether defects that they see have been rectified in development (or whether they are re-appearing after already being fixed); 
<LI>Everybody needs to be able to communicate effectively using the same language, and have a common terminology for release versions – particularly if there are multiple threads of development; </LI></UL>
<P>A good build infrastructure will provide all of the above information, and more besides.</P>
<P>Best Practice: The build should tell all project participants what they need to know</P>
<H2>Deployment Best Practices</H2>
<P>Considering that it is generally an important milestone on a project plan, normally resulting in payment or a staged payment, deployment is one of the most overlooked areas of software development.</P>
<P>The normal course of events is:</P>
<OL>
<LI>Release artifacts are created; 
<LI>Some installation and release notes are cobbled together in the form of a README; 
<LI>The deployment team work frantically to install and configure the application – the testing team (or, worse still, the customer) are idle and unproductive in the meantime; 
<LI>Some symptoms are found which are suspected to be application defects; 
<LI>The development team blame the environment; 
<LI>The deployment team blame the application; 
<LI>Repeat (5) and (6) <EM>ad nauseam</EM>. </LI></OL>
<P>When a documentation team are also considered - responsible for creating documentation that the end user will need to install, configure and use the application – the situation becomes even more difficult.</P>
<P>This situation can be avoided by planning for deployment from the beginning. Deployment is an inevitable part of software development, yet it always seems to take people by surprise.</P>
<P>Best Practice: Know that deployment is inevitable, and incorporate it into the automated processes</P>
<H2>Deployment Is Not Installation</H2>
<P>As part of normal development activities, artifacts are installed into sandbox environments – and test environments – many times. But this is not deployment, this is installation.</P>
<P>In order to get an application into its production environment, be that an internal environment or on hosted-infrastructure, a number of hurdles must be overcome:</P>
<UL>
<LI>The application must pass UAT; 
<LI>The application must be installed and configured correctly: 
<LI>All pre-requisites for the application must be satisfied; 
<LI>The end customer must accept the handover; </LI></UL>
<P>Deployment is that point in the life of an application where it starts to produce a return on investment. “<EM>Launch</EM>”, “<EM>Go-live</EM>”, “<EM>Release</EM>”, “<EM>First Customer Shipment</EM>” are all phrases which describe the same event.</P>
<P>Best Practice: Deployment is the point where an application starts to provide a return on the development investment.</P>
<H2>The Environment Is a Refactorable Component</H2>
<P>This point cannot be stressed enough, particularly in large distributed applications.</P>
<P>Every application, large or small, has a runtime environment in which it operates. In a simple desktop application, this is a standalone machine (such as a PC). In larger applications, this will be a combination of machines (e.g. an application server and a database) operating together to provide the runtime environment.</P>
<P>In either case, the application expects certain facilities to be available from the runtime environment and will function incorrectly – or cease to function – if these are not present .</P>
<P>The environment itself, whether standalone or a network, contains many moving parts that can be independently configured. IP addresses, or hostnames, can be changed. User privileges can be modified or revoked. Files and directories can be removed. Each of these can have an effect on the way that the application behaves.</P>
<P>In an environment that is owned and managed internally this can be bad enough. In an environment that is owned and managed by an external third party, and where project success is contingent upon successful UAT in that environment, this can be disastrous.</P>
<P>Best Practice: Be able to identify whether the deployment environment is as prescribed, and “<EM>fit for deployment</EM>”</P><B>Environment Verification Testing</B> 
<P>One of the most common questions that arises in development projects containing more than one environment is, simply, “<EM>are these environments the same?</EM>” and its answer can be elusive.</P>
<P>It is essential to be able to answer that question – quickly and accurately – so that any perceived defects in the application can be categorised as “<EM>defect</EM>” or “<EM>environmental</EM>”.</P>
<P>This ability becomes particularly poignant where on or more of the environments are owned by different teams, or organisations.</P>
<P>Best Practice: Be able to prescribe what the deployment environment should look like, and have a capability to test it quickly.</P><B>Regression Testing</B> 
<P>The environment, as explained earlier, is a refactorable component. It can be changed, and parts can be moved or deleted. However, unlike application code, changes may need to be made to the environment in response to external events (e.g. hardware failure, or security policies).</P>
<P>Applications, particularly complex ones, use regression tests to ensure that observed behaviour after a change is exactly as it was before the change was made. The same should be true of the environment.</P>
<P>Best Practice: Automated regression tests for the environment that will compare observed behaviour both before and after changes are made.</P>
<P>For example, suppose that a number of operating system patches or service packs are applied to an environment where the application has been, or will be, deployed. How are these tested? Do you wait for users, or testers, to start calling to say that there are problems?</P>
<P>Or do you make sure that you know what problems have been introduced before your users do?</P><B>Configuration Management</B> 
<P>As stated earlier, the SCM repository should be used to store any artifact that can be changed and that may have an effect on the environment.</P>
<P>It may not seem obvious, but some of the most obscure environmental changes can cause an application to fail:</P>
<UL>
<LI>Hostname resolution; 
<LI>Non-existent user or group accounts; 
<LI>IP and network connectivity; 
<LI>Existence, or otherwise, of files and directories ; 
<LI>Application or operating system configuration files; </LI></UL>
<P>It is essential that these environmental variables be placed under configuration control and able to be identified as part of a baseline.</P>
<P>Best Practice: Environmental artifacts that are not part of the application should be part of the baseline</P>
<H2>Automate, Automate, Automate</H2>
<P>Every single task that is performed as part of a development project – throughout the entire lifecycle – can be placed into one of two categories:</P>
<OL>
<LI>Tasks which require some form of human judgment; 
<LI>Tasks which do not; </LI></OL>
<P>Tasks which fall into the first category can use some degree of automation, but should stop and wait for human intervention wherever judgment is required.</P>
<P>Tasks in the second category should be automated. There is no value in having expensive resources employed to do mechanical or repetitive tasks that a computer could do more quickly, accurately and consistently.</P>
<P>Best Practice: Automate anything that does not require human judgment</P>
<P>A note of caution - it may be tempting to think that automation will increase productivity on its own, but this is not necessarily the case. Automating an inefficient process will simply magnify its inefficiency – as explained in the section on <STRONG><EM>Software Tools are Only Part of the Answer</EM></STRONG>.</P>
<P>This, and it is worth repeating, is a common error – to assume that automated build software alone will improve productivity.</P>
<P>Best Practice: Do not automate inefficient processes, or you will only maximize the inefficiency</P>
<H2>About BuildMonkey</H2>
<P>BuildMonkey is a division of Nemean Technology Limited - a leading technical innovator specialising in Agile Deployment and build management.</P>
<P>We have over a decade of experience in helping clients increase productivity in their build, integration and test cycles. We have a track record of massively reducing costs and defects through process automation and proven methodologies.</P>
<P>Formed in 1999, and profitable every quarter, we invented the discipline of BuildMaster - <STRONG>we are the original and the best.</STRONG></P>
<P>We provide specialist Build Management products and services - when all you do is Build Management, you get pretty good at Build Management. Our world-class Professional Services staff are the best in their field, complemented by original software products of the finest quality.</P>
<P>We aim to be the leading provider of Build Management products and services in the UK by providing excellent service to our customers, and by empowering Software Project Managers to aim for <STRONG><EM>release on-time, on-budget, with no defects</EM></STRONG>.</P><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/2600.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> 2005-03-30 10:35 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/03/30/2600.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TSS 2005 Java Symposium votion(zz)</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/03/22/2307.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Tue, 22 Mar 2005 00:36:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/03/22/2307.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/2307.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/03/22/2307.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/2307.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/2307.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width=300 align=center>
<TBODY>
<TR>
<TD colSpan=2>
<H2><A href="http://www.theserverside.com/articles/article.tss?l=TSSJS2005">http://www.theserverside.com/articles/article.tss?l=TSSJS2005</A></H2>
<H2>Attendee Opinions</H2>Every morning at the Symposium we asked the audience a set of questions (submitted by the attendees) about their opinions of things, using a live hand-held survey technology that would then spit the results up onto a powerpoint slide. What followed was a fascinating look at the perspectives of the Java developers in attendance:<BR><BR></TD></TR>
<TR>
<TD width=419 colSpan=2 height=21><STRONG>Should Java be open sourced?</STRONG></TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 height=21>Yes</TD>
<TD align=right height=21>58.6%</TD></TR>
<TR>
<TD width=419 height=21>No</TD>
<TD align=right height=21>41.4%</TD></TR>
<TR>
<TD height=21>Vote count:</TD>
<TD align=right height=21>239</TD></TR>
<TR>
<TD height=21></TD>
<TD height=21></TD></TR>
<TR>
<TD width=419 colSpan=2 height=40><STRONG>How does your organization treat open source software?</STRONG></TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 height=21>No policy. Do what you want</TD>
<TD align=right height=21>31.8%</TD></TR>
<TR>
<TD width=419 height=40>Use it if a senior team member can approve it</TD>
<TD align=right height=40>23.4%</TD></TR>
<TR>
<TD width=419 height=21>Mgt or higher has to approve its use</TD>
<TD align=right height=21>16.9%</TD></TR>
<TR>
<TD width=419 height=40>Formal review process including legal dept. approval</TD>
<TD align=right height=40>22.9%</TD></TR>
<TR>
<TD width=419 height=21>What is open source? We buy everything</TD>
<TD align=right height=21>5.0%</TD></TR>
<TR>
<TD height=21>Vote count:</TD>
<TD align=right height=21>201</TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 colSpan=2 height=40><STRONG>What is the biggest challenge in designing web applications?</STRONG></TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Application maintainability</FONT></TD>
<TD align=right height=21><FONT color=#008000>34.3%</FONT></TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Ease of development</FONT></TD>
<TD align=right height=21><FONT color=#008000>27.1%</FONT></TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Fit with existing architecture</FONT></TD>
<TD align=right height=21><FONT color=#008000>18.1%</FONT></TD></TR>
<TR>
<TD width=419 height=40><FONT color=#008000>The ability to leverage existing developers' skills</FONT></TD>
<TD align=right height=40><FONT color=#008000>9.5%</FONT></TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Code re-use</FONT></TD>
<TD align=right height=21><FONT color=#008000>11.0%</FONT></TD></TR>
<TR>
<TD height=21>Vote count:</TD>
<TD align=right height=21>210</TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 colSpan=2 height=21><STRONG>What does "RIA" Stand for? </STRONG></TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 height=21>Really Interesting Architecture</TD>
<TD align=right height=21>1.4%</TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Rich Internet Application</FONT></TD>
<TD align=right height=21><FONT color=#008000>63.3%</FONT></TD></TR>
<TR>
<TD width=419 height=21>Rolling in Acronyms</TD>
<TD align=right height=21>11.4%</TD></TR>
<TR>
<TD width=419 height=21>All of the above</TD>
<TD align=right height=21>23.8%</TD></TR>
<TR>
<TD height=21>Vote count:</TD>
<TD align=right height=21>210</TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 colSpan=2 height=21><STRONG>What is your preferred Java IDE?</STRONG></TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Eclipse</FONT></TD>
<TD align=right height=21><FONT color=#008000>53.3%</FONT></TD></TR>
<TR>
<TD width=419 height=21>emacs</TD>
<TD align=right height=21>2.1%</TD></TR>
<TR>
<TD width=419 height=21>IDEA</TD>
<TD align=right height=21>19.8%</TD></TR>
<TR>
<TD width=419 height=21>Java Studio</TD>
<TD align=right height=21>0.8%</TD></TR>
<TR>
<TD width=419 height=21><FONT color=#800080><STRONG>JBuilder</STRONG></FONT></TD>
<TD align=right height=21><FONT color=#800080><STRONG>6.6%</STRONG></FONT></TD></TR>
<TR>
<TD width=419 height=21>JDeveloper</TD>
<TD align=right height=21>3.3%</TD></TR>
<TR>
<TD width=419 height=21>Netbeans</TD>
<TD align=right height=21>2.5%</TD></TR>
<TR>
<TD width=419 height=21>vim</TD>
<TD align=right height=21>3.3%</TD></TR>
<TR>
<TD width=419 height=21>WSAD</TD>
<TD align=right height=21>7.4%</TD></TR>
<TR>
<TD width=419 height=21>other</TD>
<TD align=right height=21>0.8%</TD></TR>
<TR>
<TD height=21>Vote count:</TD>
<TD align=right height=21>242</TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 colSpan=2 height=21><STRONG>What is your preferred Web framework </STRONG></TD></TR>
<TR>
<TD height=21>&nbsp;</TD>
<TD height=21>&nbsp;</TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Struts</FONT></TD>
<TD align=right height=21><FONT color=#008000>47.0%</FONT></TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Spring</FONT></TD>
<TD align=right height=21><FONT color=#008000>20.9%</FONT></TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Tapestry</FONT></TD>
<TD align=right height=21><FONT color=#008000>7.9%</FONT></TD></TR>
<TR>
<TD width=419 height=21><FONT color=#008000>Webwork</FONT></TD>
<TD align=right height=21><FONT color=#008000>8.8%</FONT></TD></TR>
<TR>
<TD width=419 height=21>Other</TD>
<TD align=right height=21>15.3%</TD></TR>
<TR>
<TD height=21>Vote count:</TD>
<TD align=right height=21>215</TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/2307.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> 2005-03-22 08:36 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/03/22/2307.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用PippoProxy替代Apache-Tomcat，提高Tomcat的静态内容的性能（转载）</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/03/06/1767.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Sun, 06 Mar 2005 06:38:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/03/06/1767.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/1767.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/03/06/1767.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/1767.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/1767.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: PippoProxy是一个100％的纯Java的HTTP代理，它可以用来代替标准的Apache-Tomcat解决方案。与标准的Apache-Tomcat配置相比，PippoProxy可以具有以下优点：满足内部安全策略要求、无需Apache服务器、更高的性能。由于PippoProxy提供了静态内容缓存，因此在静态内容访问方面有着更高的性能。此外，PippoProxy无需任何附加的插件模块，甚至无需W...&nbsp;&nbsp;<a href='http://www.blogjava.net/jinfeng_wang/archive/2005/03/06/1767.html'>阅读全文</a><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/1767.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> 2005-03-06 14:38 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/03/06/1767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>