java學(xué)習(xí)心得筆記
j2ee學(xué)習(xí)筆記
注:框架可以用word菜單中的 “視圖/文檔結(jié)構(gòu)圖” 看到
j2ee模式
value object(值對(duì)象) 用于把數(shù)據(jù)從某個(gè)對(duì)象/層傳遞到其他對(duì)象/層的任意java對(duì)象。
通常不包含任何業(yè)務(wù)方法。
也許設(shè)計(jì)有公共屬性,或者提供可以獲取屬性值的get方法。
jsp
1.jsp的基礎(chǔ)知識(shí)
__
_____ | directive (指令)
| |-- scripting (腳本)
jsp -------| |__ action (動(dòng)作)
|
|_____template data :除jsp語(yǔ)法外,jsp引擎不能解讀的東西
1)在jsp中使用的directive(指令)主要有三個(gè):
a) page指令
b) include指令
c) taglib指令
在jsp的任何地方,以任何順序,一個(gè)頁(yè)面可以包含任意數(shù)量的page指令
2)scripting(腳本)包括三種類型
a) <%!declaraction %>;
b) <% scriptlet %>;
c) <%=expression %>;
3)action(動(dòng)作)
標(biāo)準(zhǔn)的動(dòng)作類型有:
a) <jsp:usebean>;
b) <jsp:setproperty>;
d) <jsp:getproperty>;
e) <jsp:param>;
f) <jsp:include>;
g) <jsp:forward>;
h) <jsp:plugin>;
1. 注釋: <% -----jsp comment-------%>;
<! -----html comment-------%>;
2. <%@ page session=“true” import=”java.util.*” %>;
session可以不賦值,默認(rèn)為true,如果session=”false”,則在jsp頁(yè)面中,隱含的變量session就不能使用。
3. 請(qǐng)求控制器結(jié)構(gòu)(request controller)
也被稱之為jsp model 2 architecture
這種途徑涉及到使用一個(gè)servlet或一個(gè)jsp作為一個(gè)應(yīng)用程序或一組頁(yè)面的入口點(diǎn)。
為創(chuàng)建可維護(hù)的jsp系統(tǒng),request controller是最有用的方式之一。
不是jsp,而是java類才是放置控制邏輯的正確的地方。
請(qǐng)求控制器的命名模式為: xxxcontroller.jsp
請(qǐng)求控制器類的命名模式為: xxxrequestcontroller
2.jsp中的javabean
jsp三種bean的類型
1) 頁(yè)面bean
2) 會(huì)話bean
3) 應(yīng)用bean
大多數(shù)的系統(tǒng)會(huì)使用一個(gè)會(huì)話bean來保持狀態(tài),而對(duì)每一個(gè)頁(yè)面使用一個(gè)頁(yè)面bean 來對(duì)復(fù)雜的數(shù)據(jù)進(jìn)行表示。
頁(yè)面bean是一個(gè)模型,而jsp是一個(gè)視圖。
3.custom tag
bean是信息的攜帶者,
而tag更適用于處理信息。
標(biāo)記庫(kù)包含一個(gè)標(biāo)記庫(kù)描述符(tld)和用于實(shí)現(xiàn)custom tag的java類
在翻譯階段,jsp容器將使用tld來驗(yàn)證頁(yè)面中的所有的tag是否都被正確的使用。
標(biāo)記處理程序只是一個(gè)簡(jiǎn)單的適配器,而真正的邏輯是在另一個(gè)類中實(shí)現(xiàn)的,標(biāo)記處理程序只是提供了一個(gè)供其他的可復(fù)用的類的jsp接口
servlet
1.servletconfig
? 一個(gè)servletconfig對(duì)象是servlet container在servlet initialization的時(shí)候傳遞給servlet的。
servletconfig包涵 servletcontext 和 一些 name/value pair (來自于deployment descriptor)
? servletcontext接口封裝了web應(yīng)用程序的上下文概念。
2.會(huì)話跟蹤
1) session
? 當(dāng)一個(gè)client請(qǐng)求多個(gè)servlets時(shí),一個(gè)session可以被多個(gè)servlet共享。
? 通常情況下,如果server detect到browser支持cookie,那么url就不會(huì)重寫。
2) cookie
? 在java servlet中,如果你光 cookie cookie=new cookie(name,value)
那么當(dāng)用戶退出browser時(shí),cookie會(huì)被刪除掉,而不會(huì)被存儲(chǔ)在客戶端的硬盤上。
如果要存儲(chǔ) cookie,需加一句 cookie.setmaxage(200)
? cookie是跟某一個(gè)server相關(guān)的,運(yùn)行在同一個(gè)server上的servlet共享一個(gè)cookie.
3) url rewriting
在使用url rewriting來維護(hù)session id的時(shí)候,每一次http請(qǐng)求都需要encodeurl()
典型的用在兩個(gè)地方
1) out.print(“form action=” ”);
out.print(response.encodeurl(“sessionexample”));
out.print(“form action=” ”);
out.print(“method=get>;”);
2) out.print(“<p>;<a href=” ”);
out.print(response.encodeurl(“sessionexample?database=foo&datavalue=bar”));
out.println(“” >;url encoded </a>;”);
3.singlethreadmodel
默認(rèn)的,每一個(gè)servlet definition in a container只有一個(gè)servlet class的實(shí)例。
只有實(shí)現(xiàn)了singlethreadmodel,container才會(huì)讓servlet有多個(gè)實(shí)例。
servlet specification上建議,不要使用synchronized,而使用singlethreadmodel。
singlethreadmodel(沒有方法)
保證servlet在同一時(shí)刻只處理一個(gè)客戶的請(qǐng)求。
singlethreadmodel是耗費(fèi)資源的,特別是當(dāng)有大量的請(qǐng)求發(fā)送給servlet時(shí),singlethreadmodel的作用是使包容器以同步時(shí)鐘的方式調(diào)用service方法 。
這等同于在servlet的service()方法種使用synchronized.
single thread model一般使用在需要響應(yīng)一個(gè)heavy request的時(shí)候,比如是一個(gè)需要和數(shù)據(jù)庫(kù)打交道的連接。
2. 在重載servlet地init( )方法后,一定要記得調(diào)用super.init( );
3. the client通過發(fā)送一個(gè)blank line表示它已經(jīng)結(jié)束request
而the server通過關(guān)閉the socket來表示response已結(jié)束了。
4. 一個(gè)http servlet可以送三種東西給client
1) a single status code
2) any number of http headers
3) a response body
5. servlet之間信息共享的一個(gè)最簡(jiǎn)單的方法就是
system.getproperties().put(“key”,”value”);
6. post和get
post:將form內(nèi)各字段名稱和內(nèi)容放置在html header內(nèi)傳送給server
get: ?之后的查詢字符串要使用urlencode,經(jīng)過urlencode后,這個(gè)字符串不再帶有空格,以后將在server上恢復(fù)所帶有的空格。
get是web上最經(jīng)常使用的一種請(qǐng)求方法,每個(gè)超鏈接都使用這種方法。
7. web.xml就是web applicatin 的deployment descriptor
作用有:組織各類元素
設(shè)置init param
設(shè)置安全性
8. request dispatcher用來把接收到的request forward processing到另一個(gè)servlet
要在一個(gè)response里包含另一個(gè)servlet的output時(shí),也要用到request dispatcher.
9. servlet和jsp在同一個(gè)jvm中,可以通過serveltcontext的
setattribute( )
getattribute( )
removeattribute( )
來共享對(duì)象
10. 利用request.getparameter( )得到的string存在字符集問題。
可以用 strtitle=request.getparameter(“title”);
strtitle=new string(strtitle.getbytes(“8859-1”),”gb2312”);
如果你希望得到更大得兼容性
string encoding=response.getcharacterencoding();
//確定application server用什么編碼來讀取輸入的。
strtitle=new string(strtitle.getbytes(encoding),”gb2312”);
xml
1.xml基礎(chǔ)知識(shí)
1. 一個(gè)xml文檔可以分成兩個(gè)基本部分:
首部( header )
內(nèi)容( content )
2. xml名字空間規(guī)范中指定:
xml文檔中的每一個(gè)元素都處在一個(gè)名字空間中;如果沒有指定的名字空間,缺省的名字空間就是和該元素相關(guān)聯(lián)的名字空間。
3. a document that is well-formed obeys all of the rules of xml documents (nested tags, etc.)
" if a well-formed document uses a document type definition (more on these in a minute), and it follows all the rules of the dtd, then it is also a valid document
4. a tag is the text between the <angle brackets>;
" an element is the start tag, the end tag,and everything (including other elements) in between
5. 標(biāo)簽( tags ) 實(shí)際上包含了“元素”( elements ) 和 “屬性”( attributes )兩部分。
用元素( elements )來描述有規(guī)律的數(shù)據(jù)。
用屬性( attributes ) 來描述系統(tǒng)數(shù)據(jù)。
如果你有一些數(shù)據(jù)要提供給某個(gè)應(yīng)用程序,該數(shù)據(jù)就可能要用到一個(gè)元素。
如果該數(shù)據(jù)用于分類,或者用于告知應(yīng)用程序如何處理某部分?jǐn)?shù)據(jù),或者該數(shù)據(jù)從來沒有直接對(duì)客戶程序公開,那么它就可能成為一種屬性。
6. cdata (讀作:c data ) c是character的縮寫。
7.org.xml.sax.reader
/|
org.xm.l.sax.xmlreader
/|
org.apche.xerces.parsers.saxparser
2.webservice
2.1 webservice的基本概念
webservice是一種可以接收從internet或者intranet上的其它系統(tǒng)中傳遞過來的請(qǐng)求,輕量級(jí)的獨(dú)立的通訊技術(shù)。
這種技術(shù)允許網(wǎng)絡(luò)上的所有系統(tǒng)進(jìn)行交互。隨著技術(shù)的發(fā)展,一個(gè)web服務(wù)可以包含額外的指定功能并且可以在多個(gè)b2b應(yīng)用中協(xié)作通訊。
web服務(wù)可以理解請(qǐng)求中上下文的關(guān)系,并且在每一個(gè)特定的情況下產(chǎn)生動(dòng)態(tài)的結(jié)果。這些服務(wù)會(huì)根據(jù)用戶的身份,地點(diǎn)以及產(chǎn)生請(qǐng)求的原因來改變不同的處理,用以產(chǎn)生一個(gè)唯一的,定制的方案。這種協(xié)作機(jī)制對(duì)那些只對(duì)最終結(jié)果有興趣的用戶來說,是完全透明的。
uddi
在用戶能夠調(diào)用web服務(wù)之前,必須確定這個(gè)服務(wù)內(nèi)包含哪些商務(wù)方法,找到被調(diào)用的接口定義,還要在服務(wù)端來編制軟件。所以,我們需要一種方法來發(fā)布我們的web服務(wù)。
uddi (universal description, discovery, and integration) 是一個(gè)主要針對(duì)web服務(wù)供應(yīng)商和使用者的新項(xiàng)目。uddi 項(xiàng)目中的成員可以通過uddi business registry (ubr) 來操作web服務(wù)的調(diào)用,ubr是一個(gè)全球性的服務(wù)。
web服務(wù)供應(yīng)商可以在ubr中描述并且注冊(cè)他們的服務(wù)。
用戶可以在ubr中查找并定位那些他們需要的服務(wù)。
uddi是一種根據(jù)描述文檔來引導(dǎo)系統(tǒng)查找相應(yīng)服務(wù)的機(jī)制。
uddi包含標(biāo)準(zhǔn)的“白皮書”類型的商業(yè)查詢方式,
“黃皮書”類型的局部查找,以及
“綠皮書”類型的服務(wù)類型查找。
uddi利用soap消息機(jī)制(標(biāo)準(zhǔn)的xml/http)來發(fā)布,編輯,瀏覽以及查找注冊(cè)信息。它采用xml格式來封裝各種不同類型的數(shù)據(jù),并且發(fā)送到注冊(cè)中心或者由注冊(cè)中心來返回需要的數(shù)據(jù)。
wsdl
對(duì)于商業(yè)用戶來說,要找到一個(gè)自己需要使用的服務(wù),他必須知道如何來調(diào)用。
wsdl (web services description language) 規(guī)范是一個(gè)描述接口,語(yǔ)義以及web服務(wù)為了響應(yīng)請(qǐng)求需要經(jīng)常處理的工作的xml文檔。這將使簡(jiǎn)單地服務(wù)方便,快速地被描述和記錄。
以下是一個(gè)wsdl的樣例:
<?xml version="1.0"?>;
<definitions name="stockquote"
targetnamespace="http://example.com/stockquote.wsdl"
xmlns:tns="http://example.com/stockquote.wsdl"
xmlns:xsd1="http://example.com/stockquote.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">;
<types>;
<schema targetnamespace=http://example.com/stockquote.xsd
xmlns="http://www.w3.org/xx/10/xmlschema">;
<element name="tradepricerequest">;
<complextype>;
<all>;
<element name="tickersymbol" type="string"/>;
</all>;
</complextype>;
</element>;
<element name="tradeprice">;
<complextype>;
<all>;
<element name="price" type="float"/>;
</all>;
</complextype>;
</element>;
</schema>;
</types>;
<message name="getlasttradepriceinput">;
<part name="body" element="xsd1:tradepricerequest"/>;
</message>;
<message name="getlasttradepriceoutput">;
<part name="body" element="xsd1:tradeprice"/>;
</message>;
<porttype name="stockquoteporttype">;
<operation name="getlasttradeprice">;
<input message="tns:getlasttradepriceinput"/>;
<output message="tns:getlasttradepriceoutput"/>;
</operation>;
</porttype>;
<binding name="stockquotesoapbinding"
type="tns:stockquoteporttype">;
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>;
<operation name="getlasttradeprice">;
<soap:operation
soapaction="http://example.com/getlasttradeprice"/>;
<input>;
<soap:body use="literal"/>;
</input>;
<output>;
<soap:body use="literal"/>;
</output>;
</operation>;
</binding>;
<service name="stockquoteservice">;
<documentation>;my first service</documentation>;
<port name="stockquoteport" binding="tns:stockquotebinding">;
<soap:address location="http://example.com/stockquote"/>;
</port>;
</service>;
</definitions>;
它包含了以下的關(guān)鍵信息:
消息的描述和格式定義可以通過xml文檔中的<types>;和<message>; 標(biāo)記來傳送。
<porttype>; 標(biāo)記中表示了消息傳送機(jī)制。 (e.g. request-only, request-response, response-only) 。
<binding>; 標(biāo)記指定了編碼的規(guī)范 。
<service>; 標(biāo)記中表示服務(wù)所處的位置 (url)。
wsdl在uddi中總是作為一個(gè)接口描述文檔。因?yàn)閡ddi是一個(gè)通用的用來注冊(cè)wsdl規(guī)范的地方,uddi的規(guī)范并不限制任何類型或者格式描述文檔。這些文檔可能是一個(gè)wsdl文檔,或者是一個(gè)正規(guī)的包含導(dǎo)向文檔的web頁(yè)面,也可能只是一個(gè)包含聯(lián)系信息的電子郵件地址。
現(xiàn)在java提供了一個(gè) java api for wsdl (jwsdl)規(guī)范。它提供了一套能快速處理wsdl文檔的方法,并且不用直接對(duì)xml文檔進(jìn)行操作,它會(huì)比jaxp更方便,更快速。
soap
當(dāng)商業(yè)用戶通過uddi找到你的wsdl描述文檔后,他通過可以simple object access protocol (soap) 調(diào)用你建立的web服務(wù)中的一個(gè)或多個(gè)操作。
soap是xml文檔形式的調(diào)用商業(yè)方法的規(guī)范,它可以支持不同的底層接口,象http(s)或者smtp。
之所以使用xml是因?yàn)樗莫?dú)立于編程語(yǔ)言,良好的可擴(kuò)展性以及強(qiáng)大的工業(yè)支持。之所以使用http是因?yàn)閹缀跛械木W(wǎng)絡(luò)系統(tǒng)都可以用這種協(xié)議來通信,由于它是一種簡(jiǎn)單協(xié)議,所以可以與任何系統(tǒng)結(jié)合,還有一個(gè)原因就是它可以利用80端口來穿越過防火墻。
soap的強(qiáng)大是因?yàn)樗?jiǎn)單。soap是一種輕量級(jí)的,非常容易理解的技術(shù),并且很容易實(shí)現(xiàn)。它有工業(yè)支持,可以從各主要的電子商務(wù)平臺(tái)供應(yīng)商那里獲得。
從技術(shù)角度來看,soap詳細(xì)指明了如何響應(yīng)不同的請(qǐng)求以及如何對(duì)參數(shù)編碼。一個(gè)soap封裝了可選的頭信息和正文,并且通常使用http post方法來傳送到一個(gè)http 服務(wù)器,當(dāng)然其他方法也是可以的,例如smtp。soap同時(shí)支持消息傳送和遠(yuǎn)程過程調(diào)用。以下是一個(gè)soap請(qǐng)求。
post /stockquote http/1.1
host: www.stockquoteserver.com
content-type: text/xml; charset="utf-8"
content-length: nnnn
soapaction: "some-uri"
<soap-env:envelope
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
soap-env:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/"/>;
<soap-env:header>;
<t:transaction xmlns:t="some-uri" soap-env:mustunderstand="1">;
5
</t:transaction>;
</soap-env:header>;
<soap-env:body>;
<m:getlasttradeprice xmlns:m="some-uri">;
<symbol>;sunw</symbol>;
</m:getlasttradeprice>;
</soap-env:body>;
</soap-env:envelope>;
jaxr
為了支持uddi在java平臺(tái)上的功能,java apis for xml registries (jaxr)允許開發(fā)者來訪問注冊(cè)中心。
值得注意的是,jaxr并不是建立web服務(wù)必需的,你可以利用其他常用的xml apis來直接集成這些協(xié)議。
jaxr是一個(gè)方便的api,它提供了java api來發(fā)布,查找以及編輯那些注冊(cè)信息。它的重點(diǎn)在于基于xml的b2b應(yīng)用,復(fù)雜的地址本查找以及對(duì)xml消息訂閱的支持等web服務(wù)。
它也可以用來訪問其他類型的注冊(cè)中心,象ebxml注冊(cè)中心。
這些對(duì)web服務(wù)的注冊(cè)信息進(jìn)行的操作,可以使用當(dāng)前的一些web服務(wù)工具來完成(例如第三方的soap和ebxml消息工具)。另外,當(dāng)jaxp提供了一致并具有針對(duì)性的api來完成這些操作,這將使開發(fā)變得更加容易。
jax/rpc
為了使開發(fā)人員專注于建立象soap那樣的基于xml的請(qǐng)求,jcp正在開發(fā)基于rpc (jax/rpc) 的java api。jax/rpc是用來發(fā)送和接收方法調(diào)用請(qǐng)求的,它基于xml協(xié)議,象soap,或者其他的象xmlp (xml protocol,要了解更多可以參考http://www.w3.org/xx/xp/)。jax/rpc使你不用再關(guān)注這些協(xié)議的規(guī)范,使應(yīng)用的開發(fā)更快速。不久,開發(fā)人員就不用直接以xml表示方法調(diào)用了。
目前有很多第三方實(shí)現(xiàn)了soap,開發(fā)人員可以在不同的層次上調(diào)用soap,并選擇使用哪一種。將來,jax/rpc會(huì)取代這些apis并提供一個(gè)統(tǒng)一的接口來構(gòu)造以及處理soap rpc請(qǐng)求。
在接收一個(gè)從商業(yè)伙伴那里過來的soap請(qǐng)求的時(shí)候,一個(gè)java servlet用jax/rpc來接收這個(gè)基于xml的請(qǐng)求。一旦接收到請(qǐng)求后,servlet會(huì)調(diào)用商務(wù)方法,并且把結(jié)果回復(fù)給商業(yè)伙伴。
jaxm
當(dāng)從商業(yè)合作伙伴那里接收一個(gè)web服務(wù)的請(qǐng)求時(shí),我們需要java api實(shí)現(xiàn)一個(gè)servlet來處理ebxml消息,就象我們用jax/rpc來處理soap請(qǐng)求一樣。
java api for xml messaging (jaxm) 是集成xml消息標(biāo)準(zhǔn)(象ebxml消息或者soap消息)的規(guī)范。
這個(gè)api是用來推動(dòng)xml消息處理的,它檢測(cè)那些預(yù)定單的消息格式以及約束。它控制了所有的消息封裝機(jī)制,用一種直觀的方式分割了消息中的信息,象路由信息,發(fā)貨單。這樣,開發(fā)人員只要關(guān)注消息的有效負(fù)載,而不用去擔(dān)心那些消息的重復(fù)處理。
目前的開發(fā)人員用jaxp來實(shí)現(xiàn)jaxm將要提供的功能,jaxm將會(huì)提供一套非常具有針對(duì)性的api來處理基于xml的消息傳送。這將大大簡(jiǎn)化開發(fā)人員的代碼,并使它們具有統(tǒng)一的接口。
jaxm和jax/rpc的差別在于處理消息導(dǎo)向的中間件以及遠(yuǎn)程過程調(diào)用的不同。jaxm注重于消息導(dǎo)向,而jax/rpc是用來完成遠(yuǎn)程過程調(diào)用的。以下是圖解。
請(qǐng)注意,在jaxm 和 jax/rpc技術(shù)成熟之前,開發(fā)人員還是依賴于第三方的soap apis,象apache soap, idooxoap, 以及 glue。當(dāng)jaxm 和 jax/rpc正式發(fā)布后,它將為當(dāng)前不同的soap和ebxml消息提供統(tǒng)一的接口。就象jdbc位多種不同的數(shù)據(jù)庫(kù)提供統(tǒng)一的接口。
jaxb
xml綁定技術(shù)可以把xml文檔和java對(duì)象進(jìn)行自由轉(zhuǎn)換。
用jaxb,你可以在后臺(tái)的ejb層,把xml文檔轉(zhuǎn)換成java對(duì)象。同樣你也可以把從ejb中取出的java對(duì)象轉(zhuǎn)換成xml文檔返回給用戶。
jaxb接口提供了比sax和dom更高級(jí)的方法來處理xml文檔。它提供的特性可以在xml數(shù)據(jù)和java類之間互相映射,提供了一個(gè)簡(jiǎn)單的方法來轉(zhuǎn)換xml數(shù)據(jù)。它比逐個(gè)解析標(biāo)記更簡(jiǎn)單。
2.2 建立weservice的步驟
在建立weservice的時(shí)候,有三個(gè)主要步驟:
1.建立客戶端聯(lián)接
為了允許applets,applications,商業(yè)合作伙伴,瀏覽器和pdas 使用web服務(wù)。
2.實(shí)現(xiàn)web服務(wù)
包括工作流,數(shù)據(jù)傳送,商業(yè)邏輯以及數(shù)據(jù)訪問。這些功能是隱藏在web服務(wù)后,并且為客戶端工作的。
3.聯(lián)接后臺(tái)系統(tǒng)
這個(gè)系統(tǒng)可能包括一個(gè)或多個(gè)數(shù)據(jù)庫(kù),現(xiàn)存的企業(yè)信息系統(tǒng),商業(yè)合作伙伴自己的系統(tǒng)或者web服務(wù),以及在多個(gè)系統(tǒng)中共享的數(shù)據(jù)。
基于j2ee的web服務(wù)的核心構(gòu)架:
rmi
1. rmi-iiop
2. rmi 是在java中使用remote method invocation的最初的方法,rmi使用java.rmi包
rmi-iiop 是rmi的一個(gè)特殊版本,rmi-iiop可以和corba兼容,rmi-iiop使用java.rmi包和javax.rmi
jaf(java活動(dòng)構(gòu)架)
開發(fā)者可以使用jaf來決定任意一塊數(shù)據(jù)的類型、封裝對(duì)數(shù)據(jù)的訪問、尋找合適的操作、實(shí)例化相關(guān)的bean來執(zhí)行這些操作等。
例如,javamail就是使用jaf根據(jù)mime類型來決定實(shí)例化那一個(gè)對(duì)象。
ejb
1. ejb組件實(shí)現(xiàn)代碼的限制
ejb組件的約束
ejb的開發(fā)者并不需要在ejb的組件實(shí)現(xiàn)代碼中編寫系統(tǒng)級(jí)的服務(wù),ejb提供商/開發(fā)
者需知道并且嚴(yán)格地遵守一些限制,這些限制與開發(fā)穩(wěn)定的和可移植的ejb組件的利益有
關(guān)。
以下是你應(yīng)該回避使用的一些java特色,并且在你的ejb組件的實(shí)現(xiàn)代碼中要嚴(yán)格限
制它們的使用:
1.使用static,非final 字段。建議你在ejb組件中把所有的static字段都聲明為final型的。這樣可以保證前后一致的運(yùn)行期語(yǔ)義,使得ejb容器有可以在多個(gè)java虛擬機(jī)之間分發(fā)組件實(shí)例的靈活性。
2.使用線程同步原語(yǔ)來同步多個(gè)組件實(shí)例的運(yùn)行。避免這個(gè)問題,你就可以使ejb容器靈活的在多個(gè)java虛擬機(jī)之間分發(fā)組件實(shí)例。
3.使用awt函數(shù)完成鍵盤的輸入和顯示輸出。約束它的原因是服務(wù)器方的商業(yè)組件意味著提供商業(yè)功能而不包括用戶界面和鍵盤的i/o功能。
4.使用文件訪問/java.io 操作。ejb商業(yè)組件意味著使用資源管理器如jdbc來存儲(chǔ)和檢索數(shù)據(jù)而不是使用文件系統(tǒng)api。同時(shí),部署工具提供了在部署描述器(descriptor)中存儲(chǔ)環(huán)境實(shí)體,以至于ejb組件可以通過環(huán)境命名上下文用一種標(biāo)準(zhǔn)的方法進(jìn)行環(huán)境實(shí)體查詢。所以,使用文件系統(tǒng)的需求基本上是被排除了。
5.監(jiān)聽和接收socket連接,或者用socket進(jìn)行多路發(fā)送。ejb組件并不意味著提供網(wǎng)絡(luò)socket服務(wù)器功能,但是,這個(gè)體系結(jié)構(gòu)使得ejb組件可以作為socket客戶或是rmi客戶并且可以和容器所管理的環(huán)境外面的代碼進(jìn)行通訊。
6.使用映象api查詢ejb組件由于安全規(guī)則所不能訪問的類。這個(gè)約束加強(qiáng)了java平臺(tái)的安全性。
7.欲創(chuàng)建或獲得一個(gè)類的加載器,設(shè)置或創(chuàng)建一個(gè)新的安全管理器,停止java虛擬機(jī),改變輸入、輸出和出錯(cuò)流。這個(gè)約束加強(qiáng)了安全性同時(shí)保留了ejb容器管理運(yùn)行環(huán)境的能力。
8.設(shè)置socket工廠被url's serversocket,socket和stream handler使用。避免這個(gè)特點(diǎn),可以加強(qiáng)安全性同時(shí)保留了ejb容器管理運(yùn)行環(huán)境的能力。
9.使用任何方法啟動(dòng)、停止和管理線程。這個(gè)約束消除了與ejb容器管理死鎖、線程
和并發(fā)問題的責(zé)任相沖突的可能性。
通過限制使用10-16幾個(gè)特點(diǎn),你的目標(biāo)是堵上一個(gè)潛在的安全漏洞:
10.直接讀寫文件描述符。
11.為一段特定的代碼獲得安全策略信息。
12.加載原始的類庫(kù)。
13.訪問java一般角色所不能訪問的包和類。
14.在包中定義一個(gè)類。
15.訪問或修改安全配置對(duì)象(策略、安全、提供者、簽名者和實(shí)體)。
16.使用java序列化特點(diǎn)中的細(xì)分類和對(duì)象替代。
17.傳遞this引用指針作為一個(gè)參數(shù)或者作為返回值返回this引用指針。你必須使用
sessioncontext或entitycontext中的getejbobject()的結(jié)果。
java2平臺(tái)的安全策略
以上所列的特點(diǎn)事實(shí)上正是java編程語(yǔ)言和java2標(biāo)準(zhǔn)版中的標(biāo)準(zhǔn)的、強(qiáng)有力的特色。ejb容器允許從j2se中使用一些或全部的受限制的特色,盡管對(duì)于ejb組件是不可用的,但需通過j2se的安全機(jī)制來使用而不是通過直接使用j2se的api。
java2平臺(tái)為ejb1.1規(guī)范中的ejb容器所制定的安全策略定義了安全許可集,這些許可在ejb組件的編程限制中出現(xiàn)。通過這個(gè)策略,定義了一些許可諸如:java.io.filepermission,java.net.netpermission,java.io.reflect.reflectpermission,java.lang.security.securitypermission,以便加強(qiáng)先前所列出的編程限制。
許多ejb容器沒有加強(qiáng)這些限制,他們希望ejb組件開發(fā)者能遵守這些編程限制或者是帶有冒險(xiǎn)想法違背了這些限制。違背這些限制的ejb組件,比標(biāo)準(zhǔn)方法依賴過多或過少的安全許可,都將很少能在多個(gè)ejb容器間移植。另外,代碼中都將隱藏著一些不確定的、難以預(yù)測(cè)的問題。所有這些都足以使ejb組件開發(fā)者應(yīng)該知道這些編程限制,同時(shí)也應(yīng)該認(rèn)真地遵守它們。
任何違背了這些編程限制的ejb組件的實(shí)現(xiàn)代碼在編譯時(shí)都不能檢查出來,因?yàn)檫@些特點(diǎn)都是java語(yǔ)言和j2se中不可缺少的部分。
對(duì)于ejb組件的這些限制同樣適用于ejb組件所使用的幫助/訪問(helper/access)類,j2ee應(yīng)用程序使用java文檔(jar)文件格式打包到一個(gè)帶.ear(代表enterprise archive)擴(kuò)展名的文件中,這個(gè)ear文件對(duì)于發(fā)送給文件部署器來說是標(biāo)準(zhǔn)的格式。ear文件中包括在一個(gè)或多個(gè)ejb-jar文件中的ejb組件,還可能有ejb-jar所依賴的庫(kù)文件。所有ear文件中的代碼都是經(jīng)過深思熟慮開發(fā)的應(yīng)用程序并且都遵守編程限制和訪問許可集。
未來版本的規(guī)范可能會(huì)指定通過部署工具來定制安全許可的能力,通過這種方法指定了一個(gè)合法的組件應(yīng)授予的許可權(quán)限,也指定了一個(gè)標(biāo)準(zhǔn)方法的需求:如從文件系統(tǒng)中讀文件應(yīng)有哪些要求。一些ejb容器/服務(wù)器目前在它們的部署工具中都提供了比標(biāo)準(zhǔn)權(quán)限或多或少的許可權(quán)限,這些并不是ejb1.1規(guī)范中所需要的。
理解這些約束
ejb容器是ejb組件生存和執(zhí)行的運(yùn)行期環(huán)境,ejb容器為ejb組件實(shí)例提供了一些服務(wù)如:事務(wù)管理、安全持久化、資源訪問、客戶端連接。ejb容器也負(fù)責(zé)ejb組件實(shí)例整個(gè)生命期的管理、擴(kuò)展問題以及并發(fā)處理。所以,ejb組件就這樣寄居在一個(gè)被管理的執(zhí)行環(huán)境中--即ejb容器。
因?yàn)閑jb容器完全負(fù)責(zé)ejb組件的生命期、并發(fā)處理、資源訪問、安全等等,所以與容器本身的鎖定和并發(fā)管理相沖突的可能性就需要消除,許多限制都需要使用來填上潛在的安全漏洞。除了與ejb容器責(zé)任與安全沖突的問題,ejb組件還意味著僅僅聚焦于商務(wù)邏輯,它依賴于ejb容器所提供的服務(wù)而不是自己來直接解決底層的系統(tǒng)層的問題。
可能的問題
通常,ejb組件在容器之間的移植不可避免地與如下問題相關(guān):
1.它需要依靠的受限制的特點(diǎn)在特定ejb容器中沒有得到加強(qiáng)。
2.它需要依靠的非標(biāo)準(zhǔn)的服務(wù)從容器中可獲得。
為了保證ejb組件的可移植性和一致的行為,你應(yīng)該使用一個(gè)具有與java2平臺(tái)安全
策略集相一致的策略集的容器來測(cè)試ejb組件,并且其加強(qiáng)了前述的編程限制。
總結(jié)
ejb組件開發(fā)者應(yīng)該知道這些推薦的關(guān)于ejb組件的編程限制,明白它們的重要性,并且從組件的穩(wěn)定性和可移植性利益方面考慮來遵循它們。因?yàn)檫@些編程限制能阻止你使用標(biāo)準(zhǔn)的java語(yǔ)言的特點(diǎn),違背了這些編程限制在編譯時(shí)不會(huì)知道,并且加強(qiáng)這些限制也不是ejb容器的責(zé)任。所有這些原因都使你應(yīng)很小心地遵守這些編程限制,這些限制在組件的合同中已經(jīng)成為了一個(gè)條款,并且它們對(duì)于建造可靠的、可移植的組件是非常重要的。
2. 優(yōu)化ejb
entity bean為在應(yīng)用程序和設(shè)計(jì)中描述持久化商業(yè)對(duì)象(persistent business objec ts)提供了一個(gè)清晰的模型。在java對(duì)象模型中,簡(jiǎn)單對(duì)象通常都是以一種簡(jiǎn)單的方式進(jìn)行處理但是,很多商業(yè)對(duì)象所需要的事務(wù)化的持久性管理沒有得到實(shí)現(xiàn)。entity bean將持久化機(jī)制封裝在容器提供的服務(wù)里,并且隱藏了所有的復(fù)雜性。entity bean允許應(yīng)用程序操縱他們就像處理一個(gè)一般的java對(duì)象應(yīng)用。除了從調(diào)用代碼中隱藏持久化的形式和機(jī)制外,entity bean還允許ejb容器對(duì)對(duì)象的持久化進(jìn)行優(yōu)化,保證數(shù)據(jù)存儲(chǔ)具有開放性,靈活性,以及可部署性。在一些基于ejb技術(shù)的項(xiàng)目中,廣泛的使用oo技術(shù)導(dǎo)致了對(duì)entity bean的大量使用,sun的工程師們已經(jīng)積累了很多使用entity bean的經(jīng)驗(yàn),這篇文章就詳細(xì)闡述的這些卡發(fā)經(jīng)驗(yàn):
*探索各種優(yōu)化方法
*提供性能優(yōu)化和提高適用性的法則和建議
*討論如何避免一些教訓(xùn)。
法則1:只要可以,盡量使用cmp
cmp方式不僅減少了編碼的工作量,而且在container中以及container產(chǎn)生的數(shù)據(jù)庫(kù)訪問代碼中包括了許多優(yōu)化的可能。container可以訪問內(nèi)存緩沖中的bean,這就允許它可以監(jiān)視緩沖中的任何變化。這樣的話就在事物沒有提交之前,如果緩存的數(shù)據(jù)沒有變化就不用寫到數(shù)據(jù)庫(kù)中。就可以避免許多不必要的數(shù)據(jù)庫(kù)寫操作。另外一個(gè)優(yōu)化是在調(diào)用find方法的時(shí)候。通常情況下find方法需要進(jìn)行以下數(shù)據(jù)庫(kù)操作:
查找數(shù)據(jù)庫(kù)中的紀(jì)錄并且獲得主鍵
將紀(jì)錄數(shù)據(jù)裝入緩存
cmp允許將這兩步操作優(yōu)化為一步就可以搞定。[具體怎么做我也沒弄明白,原文沒有具體闡述]
法則2:寫代碼時(shí)盡量保證對(duì)bmp和cmp都支持
許多情況下,ejb的開發(fā)者可能無法控制他們寫的bean怎么樣被部署,以及使用的container是不是支持cmp.
一個(gè)有效的解決方案是,將商業(yè)邏輯的編碼完全和持久化機(jī)制分離。再cmp類中實(shí)現(xiàn)商業(yè)邏輯,然后再編寫一個(gè)bmp類,用該類繼承cmp類。這樣的話,所有的商業(yè)邏輯都在cmp類中,而持久化機(jī)制在bmp中實(shí)現(xiàn)。[我覺得這種情況在實(shí)際工作中很少遇到,但是作者解決問題的思路值得學(xué)習(xí)]
法則3:把ejbstore中的數(shù)據(jù)庫(kù)訪問減小到最少。
如果使用bmp,設(shè)置一個(gè)緩存數(shù)據(jù)改變標(biāo)志dirty非常有用。所有改變數(shù)據(jù)庫(kù)中底層數(shù)據(jù)的操作,都要設(shè)置dirty,而在ejbstore()中,首先檢測(cè)dirty的值,如果dirty的值沒有改變,表明目前數(shù)據(jù)庫(kù)中的數(shù)據(jù)與緩存的一致,就不必進(jìn)行數(shù)據(jù)庫(kù)操作了,反之,就要把緩存數(shù)據(jù)寫入數(shù)據(jù)庫(kù)。
法則4:總是將從lookup和find中獲得的引用進(jìn)行緩存。(cache)
引用緩存對(duì)session bean和entity bean 都是適用的。
通過jndi lookup獲得ejb資源。比如datasource,bean的引用等等都要付出相當(dāng)大的代價(jià)。因此應(yīng)該避免多余的lookup.可以這樣做:
將這些引用定義為實(shí)例變量。
從setentitycontext(session bean使用setsessioncontext)方法查找他們。setentitycontext方法對(duì)于一個(gè)bean實(shí)例只執(zhí)行一次,所有的相關(guān)引用都在這一次中進(jìn)行查找,這樣查找的代價(jià)就不是那么昂貴了。應(yīng)該避免在其他方法中查找引用。尤其是訪問數(shù)據(jù)庫(kù)的方法:ejbload()和ejbstore(),如果在這些頻繁調(diào)用的方法中進(jìn)行datasource的查找,勢(shì)必造成時(shí)間的浪費(fèi)。
調(diào)用其他entity bean的finder方法也是一種重量級(jí)的調(diào)用。多次調(diào)用finder()方法的代價(jià)非常高。如果這種引用不適合放在setentitycontext這樣的初始化時(shí)執(zhí)行的方法中執(zhí)行,就應(yīng)該在適當(dāng)?shù)臅r(shí)候緩存finder的執(zhí)行結(jié)果。只是要注意的是,如果這個(gè)引用只對(duì)當(dāng)前的entity有效,你就需要在bean從緩沖池中取出來代表另外一個(gè)實(shí)體時(shí)清除掉這些引用。,這些操作應(yīng)該在ejbactivate()中進(jìn)行。
法則5:總是使用prepare statements
這條優(yōu)化法則適用于所有訪問關(guān)系數(shù)據(jù)庫(kù)的操作。
數(shù)據(jù)庫(kù)在處理每一個(gè)sql statement的時(shí)候,執(zhí)行前都要對(duì)statement進(jìn)行編譯。一些數(shù)據(jù)庫(kù)具有緩存statement和statement的編譯后形式的功能。數(shù)據(jù)庫(kù)可以把新的statement和緩存中的進(jìn)行匹配。然而,如果要使用這一優(yōu)化特性,新的statement要必須和緩存中的statement完全匹配。
對(duì)于non-prepared statement,數(shù)據(jù)和statement本身作為一個(gè)字符串傳遞,這樣由于前后調(diào)用的數(shù)據(jù)不同而不能匹配,就導(dǎo)致無法使用這種優(yōu)化。而對(duì)于prepared statement,數(shù)據(jù)和statement是分開傳遞給數(shù)據(jù)庫(kù)的,這樣statement就可以和cache中已編譯的statement進(jìn)行匹配。statement就不必每次都進(jìn)行編譯操作。從而使用該優(yōu)化屬性。
這項(xiàng)技術(shù)在一些小型的數(shù)據(jù)庫(kù)訪問中能夠減少statement將近90%的執(zhí)行時(shí)間。
法則6:完全關(guān)閉所有的statement
在編寫bmp的數(shù)據(jù)庫(kù)訪問代碼時(shí),記住一定要在數(shù)據(jù)庫(kù)訪問調(diào)用之后關(guān)閉statement,因?yàn)槊總(gè)打開的statement對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的一個(gè)打開的游標(biāo)。
security
1.加密
對(duì)稱加密
(1)分組密碼
(2)流密碼
常用的對(duì)稱加密算法:
des和tripledes
blowfish
rc4
aes
非對(duì)稱加密
常用的非對(duì)稱加密算法
rsa
elgamal
會(huì)話密鑰加密(對(duì)稱加密和非對(duì)稱加密一起使用)
常用的會(huì)話密鑰加密協(xié)議
s/mime
pgp
ssl和tls ssl是在application level protocal和transport protocal之間的。
比如:http和tcp/ip之間
ssl 提供了服務(wù)器端認(rèn)證和可選的客戶端認(rèn)證,保密性和數(shù)據(jù)完整性。
提供基于ssl方式的傳輸加密和認(rèn)證,確保以下三種安全防護(hù):
數(shù)據(jù)的機(jī)密性和準(zhǔn)確性、
服務(wù)器端認(rèn)證
客戶端認(rèn)證。
客戶端認(rèn)證比服務(wù)器端認(rèn)證不很普遍的原因是每一個(gè)要被認(rèn)證的客戶都必須有一張verisign這樣的ca簽發(fā)的證書。
通常,在進(jìn)行身份認(rèn)證的時(shí)候,應(yīng)當(dāng)只接受一個(gè)ca,這個(gè)ca的名字包含在客戶證書中。
由于不可能隨意創(chuàng)建一個(gè)由指定ca簽發(fā)的證書,所以這可以有效的防御通過偽造證書來進(jìn)行的攻擊嘗試。
2.認(rèn)證(authentication)
認(rèn)證就是確定一條消息或一個(gè)用戶的可靠性的過程。
1.消息摘要
md5
sha和sha-1
2.消息認(rèn)證碼(message authientication codes,mac)
3.數(shù)字簽名
用戶可以用自己的密鑰對(duì)信息加以處理,由于密鑰僅為本人所有,這樣就產(chǎn)生了別人無法生成的文件,也就形成了數(shù)字簽名
數(shù)字簽名可以
1)保證數(shù)據(jù)的完整性
2)驗(yàn)證用戶的身份
數(shù)字簽名采用一個(gè)人的私鑰計(jì)算出來,然后用公鑰去檢驗(yàn)。
hash算法 私鑰加密
原報(bào)文 ――――――>;報(bào)文摘要( message digest ) ―――――>;數(shù)字簽名
原報(bào)文和數(shù)字簽名一起被發(fā)送到接受者那里,接受者用同樣的hash算法得到報(bào)文摘要,然后用發(fā)送者的公鑰解開數(shù)字簽名。
比較是否相同,則可以確定報(bào)文確定來自發(fā)送者。
驗(yàn)證數(shù)字簽名必須使用公鑰,但是,除非你是通過安全的方式直接得到,否則不能保證公鑰的正確性。(數(shù)字證書可以解決這個(gè)問題)
一個(gè)接受者在使用公鑰(public key)檢查數(shù)字簽名(digital signature)的可信度時(shí),通常先要檢查收到的公鑰(public key)是否可信的。
因此發(fā)送方不是單單地發(fā)送公鑰(public key),而是發(fā)送一個(gè)包含公鑰(public key)的數(shù)字證書(cetificate )。
4.數(shù)字證書
數(shù)字證書是一個(gè)經(jīng)證書授權(quán)中心數(shù)字簽名的包含公開密鑰所有者信息以及公開密鑰的文件。
數(shù)字證書cetificate中包括:
i. 用戶的公鑰(public key)
ii. 用戶的一些信息,如姓名,email
iii. 發(fā)行機(jī)構(gòu)的數(shù)字簽名(digital signature), 用于保證證書的可信度
iv. 發(fā)行機(jī)構(gòu)的一些信息
數(shù)字證書的格式遵循x.509國(guó)際標(biāo)準(zhǔn)。
注意:一個(gè)數(shù)字證書certificate并不適用于多種browser,甚至一種browser的多個(gè)版本。
數(shù)字標(biāo)識(shí)由公用密鑰、私人密鑰和數(shù)字簽名三部分組成。
當(dāng)在郵件中添加數(shù)字簽名時(shí),您就把數(shù)字簽名和公用密鑰加入到郵件中。數(shù)字簽名和公用密鑰統(tǒng)稱為證書。您可以使用 outlook express 來指定他人向您發(fā)送加密郵件時(shí)所需使用的證書。這個(gè)證書可以不同于您的簽名證書。
收件人可以使用您的數(shù)字簽名來驗(yàn)證您的身份,并可使用公用密鑰給您發(fā)送加密郵件,這些郵件必須用您的私人密鑰才能閱讀。
要發(fā)送加密郵件,您的通訊簿必須包含收件人的數(shù)字標(biāo)識(shí)。這樣,您就可以使用他們的公用密鑰來加密郵件了。當(dāng)收件人收到加密郵件后,用他們的私人密鑰來對(duì)郵件進(jìn)行解密才能閱讀。
在能夠發(fā)送帶有數(shù)字簽名的郵件之前,您必須獲得數(shù)字標(biāo)識(shí)。如果您正在發(fā)送加密郵件,您的通訊簿中必須包含每位收件人的數(shù)字標(biāo)識(shí)。
數(shù)字證書,可以是個(gè)人證書或 web 站點(diǎn)證書,用于將身份與"公開密鑰"關(guān)聯(lián)。只有證書的所有者才知道允許所有者"解密"或進(jìn)行"數(shù)字簽名"的相應(yīng)"私人密鑰"。當(dāng)您將自己的證書發(fā)送給其他人時(shí),實(shí)際上發(fā)給他們的是您的公開密鑰,這樣他們就可以向您發(fā)送只能由您使用私人密鑰解密和讀取的加密信息!
通過瀏覽器使用數(shù)字證書,必須先要設(shè)置瀏覽器軟件 internet explorer 或 netscape使用此證書,才能開始發(fā)送加密或需要數(shù)字簽名的信息。訪問安全的 web 站點(diǎn)(以"https"打頭的站點(diǎn))時(shí),該站點(diǎn)將自動(dòng)向您發(fā)送他們的web站點(diǎn)證書。
3.ca(證書授證中心)
ca機(jī)構(gòu),又稱為證書授證(certificate authority)中心,作為電子商務(wù)交易中受信任的第三方,承擔(dān)公鑰體系中公鑰的合法性檢驗(yàn)的責(zé)任。ca中心為每個(gè)使用公開密鑰的用戶發(fā)放一個(gè)數(shù)字證書,數(shù)字證書的作用是證明證書中列出的用戶合法擁有證書中列出的公開密鑰 。ca機(jī)構(gòu)的數(shù)字簽名使得攻擊者不能偽造和篡改證書。在set交易中,ca不僅對(duì)持卡人、商戶發(fā)放證書,還要對(duì)獲款的銀行、網(wǎng)關(guān)發(fā)放證書。它負(fù)責(zé)產(chǎn)生、分配并管理所有參與網(wǎng)上交易的個(gè)體所需的數(shù)字證書,因此是安全電子交易的核心環(huán)節(jié)。
對(duì)證書的信任基于對(duì)根證書的信任. 例如在申請(qǐng)sheca的個(gè)人數(shù)字證書前,需要先下載根證書,然后再進(jìn)行各類證書的申請(qǐng)。
下載根證書的目的:
網(wǎng)絡(luò)服務(wù)器驗(yàn)證(s);安全電子郵件(e)
申請(qǐng)個(gè)人數(shù)字證書可以為internet用戶提供發(fā)送電子郵件的安全和訪問需要安全連接(需要客戶證書)的站點(diǎn)。
1)個(gè)人數(shù)字證書
a.個(gè)人身份證書
個(gè)人身份證書是用來表明和驗(yàn)證個(gè)人在網(wǎng)絡(luò)上的身份的證書,它確保了網(wǎng)上交易和作業(yè)的安全性和可靠性?蓱(yīng)用于:網(wǎng)上炒股、網(wǎng)上理財(cái)、網(wǎng)上保險(xiǎn)、網(wǎng)上繳費(fèi)、網(wǎng)上購(gòu)物、網(wǎng)上辦公等等。個(gè)人身份證書可以存儲(chǔ)在軟盤或ic卡中。
b.個(gè)人安全電子郵件證書
個(gè)人安全電子郵件證書可以確保郵件的真實(shí)性和保密性。申請(qǐng)后一般是安裝在用戶的瀏覽器里。用戶可以利用它來發(fā)送簽名或加密的電子郵件。
用戶在申請(qǐng)安裝完安全安全電子郵件數(shù)字證書后,就可以對(duì)要發(fā)送的郵件進(jìn)行數(shù)字簽名。收信人收到該郵件后,就可以看到數(shù)字簽名的標(biāo)記,這樣就可以證明郵件肯定來自發(fā)信者本人,而不是別人盜用該帳號(hào)偽造信件,同時(shí)也保證該郵件在傳送過程中沒被他人篡改過任何數(shù)據(jù)。
安全電子郵件中使用的數(shù)字證書可以實(shí)現(xiàn):
保密性 通過使用收件人的數(shù)字證書對(duì)電子郵件加密。如此以來,只有收件人才能閱讀加密的郵件,在internet上傳遞的電子郵件信息不會(huì)被人竊取,即使發(fā)錯(cuò)郵件,收件人也無法看到郵件內(nèi)容。
認(rèn)證身份 在internet上傳遞電子郵件的雙方互相不能見面,所以必須有方法確定對(duì)方的身份。利用發(fā)件人數(shù)字證書在傳送前對(duì)電子郵件進(jìn)行數(shù)字簽名即可確定發(fā)件人身份,而不是他人冒充的。
完整性 利用發(fā)件人數(shù)字證書在傳送前對(duì)電子郵件進(jìn)行數(shù)字簽名不僅可確定發(fā)件人身份,而且傳遞的電子郵件信息也不能被人在傳輸過程中修改。
不可否認(rèn)性 由于發(fā)件人的數(shù)字證書只有發(fā)件人唯一擁有,故發(fā)件人利用其數(shù)字證書在傳送前對(duì)電子郵件進(jìn)行數(shù)字簽名,發(fā)件人就無法否認(rèn)發(fā)過這個(gè)電子郵件。
outlook express中的個(gè)人安全電子郵件證書
簽名郵件帶有簽名郵件圖標(biāo)。
簽名郵件可能出現(xiàn)的任何問題都將在本信息之后可能出現(xiàn)的“安全警告”中得到描述。如果存在問題,您應(yīng)該認(rèn)為郵件已被篡改,或并非來自所謂的發(fā)件人。
當(dāng)收到一封加密郵件時(shí),您應(yīng)該可以自信地認(rèn)為郵件未被任何第三者讀過。outlook express 會(huì)自動(dòng)對(duì)電子郵件解密, 如果在您的計(jì)算機(jī)上裝有正確的數(shù)字標(biāo)識(shí)。
2)企業(yè)數(shù)字證書
a.企業(yè)身份證書
企業(yè)身份證書是用來表明和驗(yàn)證企業(yè)用戶在網(wǎng)絡(luò)上身份的證書,它確保了企業(yè)網(wǎng)上交易和作業(yè)的安全性和可靠性。可應(yīng)用于:網(wǎng)上證券、網(wǎng)上辦公、網(wǎng)上交稅、網(wǎng)上采購(gòu)、網(wǎng)上資金轉(zhuǎn)帳、網(wǎng)上銀行等。企業(yè)身份證書可以存儲(chǔ)在軟盤和ic卡中!
b.企業(yè)安全電子郵件證書
企業(yè)安全電子郵件證書可以確保郵件的真實(shí)性和保密性。申請(qǐng)后一般是安裝在用戶的瀏覽器里。企業(yè)可以利用它來發(fā)送簽名或加密的電子郵件。
可使用 windows xx 中的證書服務(wù)來創(chuàng)建證書頒發(fā)機(jī)構(gòu) (ca),它負(fù)責(zé)接收證書申請(qǐng)、驗(yàn)證申請(qǐng)中的信息和申請(qǐng)者的身份、頒發(fā)證書、吊銷證書以及發(fā)布證書吊銷列表 (crl)。
通常,當(dāng)用戶發(fā)出證書申請(qǐng)時(shí),在其計(jì)算機(jī)上的加密服務(wù)提供程序 (csp) 為用戶生成公鑰和私鑰對(duì)。用戶的公鑰隨同必要的識(shí)別信息發(fā)送至 ca。如果用戶的識(shí)別信息符合批準(zhǔn)申請(qǐng)的 ca 標(biāo)準(zhǔn),那么 ca 將生成證書,該證書由客戶應(yīng)用程序檢索并就地存儲(chǔ)。
4.set
安全接口層協(xié)議——ssl(se cure socketslayer),并且已經(jīng)幾乎成為了目前www 世界的事實(shí)標(biāo)準(zhǔn)。這一標(biāo)準(zhǔn)使用公共密鑰編碼方案來對(duì)傳輸數(shù)據(jù)進(jìn)行加密,在雙方之間建立一個(gè)internet 上的加密通道,從而使第三方無法獲得其中的信息,其思路與目前流行的vpn方案大致相同,目的都是要保護(hù)數(shù)據(jù)不被未經(jīng)授權(quán)的第三方所竊聽,或即使竊聽到也不知所云。但就象vpn 一樣,ssl 在認(rèn)證方面沒有任何作為,它們都需要通過另外的手段來確認(rèn)身份和建立雙方彼此間的信任,然后再通過ssl 進(jìn)行交易。
正是由于ssl 標(biāo)準(zhǔn)在認(rèn)證方面的缺憾,所以set 才有存在的必要。set(secure electronic transactions) 規(guī)范由masterc ard 和visa 公司于1996 年發(fā)布,專家們認(rèn)為set 是保證用戶與商家在電子商務(wù)與在線交易中免受欺騙的重要手段。傳統(tǒng)的信用卡交易者總在擔(dān)心不誠(chéng)實(shí)的店員會(huì)將自己的信用卡號(hào)碼透露給他人,而在線交易也是如此,持卡者總在擔(dān)心服務(wù)器端的管理員會(huì)將信用卡號(hào)碼泄露出去,或者擔(dān)心黑客會(huì)在管理員不知情的情況下盜取信用卡號(hào)碼。事實(shí)上這些擔(dān)心都是必要的,而set 標(biāo)準(zhǔn)則可以保證用戶的信用卡號(hào)碼只傳送給信用卡公司進(jìn)行認(rèn)證,不會(huì)被系統(tǒng)管理員看到,也不會(huì)留在交易服務(wù)器的硬盤上給黑客以可乘之機(jī)。
5.pki
pki是一種易于管理的、集中化的網(wǎng)絡(luò)安全方案。它可支持多種形式的數(shù)字認(rèn)證: 數(shù)據(jù)加密、數(shù)字簽字、不可否認(rèn)、身份鑒別、密鑰管理以及交叉認(rèn)證等。pki可通過一個(gè)基于認(rèn)證的框架處理所有的數(shù)據(jù)加密和數(shù)字簽字工作。p ki標(biāo)準(zhǔn)與協(xié)議的開發(fā)迄今已有15年的歷史,目前的pki已完全可以向企業(yè)網(wǎng)絡(luò)提供有效的安全保障。
pki是一種遵循標(biāo)準(zhǔn)的密鑰管理平臺(tái),它能夠?yàn)樗芯W(wǎng)絡(luò)應(yīng)用透明地提供采用加密和數(shù)字簽名等密碼服務(wù)所必需的密鑰和證書管理。pki必須具有
1)ca、
2)證書庫(kù)、
3)密鑰備份及恢復(fù)系統(tǒng)、
4)證書作廢處理系統(tǒng)、
5)客戶端證書處理系統(tǒng)
等基本成分,構(gòu)建pki也將圍繞著這五大系統(tǒng)來構(gòu)建
一個(gè)pki由眾多部件組成,這些部件共同完成兩個(gè)主要功能:
1)為數(shù)據(jù)加密
2)創(chuàng)建數(shù)字認(rèn)證。
服務(wù)器(即后端)產(chǎn)品是這一系統(tǒng)的核心,這些數(shù)據(jù)庫(kù)管理著數(shù)字認(rèn)證、公共密鑰及專用密鑰( 分別用于數(shù)據(jù)的加密和解密)。
ca數(shù)據(jù)庫(kù)負(fù)責(zé)發(fā)布、廢除和修改x.509數(shù)字認(rèn)證信息,它裝有用戶的公共密鑰、證書有效期以及認(rèn)證功能(例如對(duì)數(shù)據(jù)的加密或?qū)?shù)字簽字的驗(yàn)證) 。為了防止對(duì)數(shù)據(jù)簽字的篡改,ca在把每一數(shù)字簽字發(fā)送給發(fā)出請(qǐng)求的客戶機(jī)之前,需對(duì)每一個(gè)數(shù)字簽字進(jìn)行認(rèn)證。一旦數(shù)字認(rèn)證得以創(chuàng)建, 它將會(huì)被自動(dòng)存儲(chǔ)于x.500目錄中,x.500目錄為樹形結(jié)構(gòu)。ldap(lightweight directory access protocol)協(xié)議將響應(yīng)那些要求提交所存儲(chǔ)的公共密鑰認(rèn)證的請(qǐng)求。ca為每一用戶或服務(wù)器生成兩對(duì)獨(dú)立的公共和專用密鑰。其中一對(duì)用于信息的加密和解密, 另一對(duì)由客戶機(jī)應(yīng)用程序使用,用于文檔或信息傳輸中數(shù)字簽字的創(chuàng)建。
大多數(shù)pki均支持證書分布,這是一個(gè)把已發(fā)布過的或續(xù)延生命期的證書加以存儲(chǔ)的過程。這一過程使用了一個(gè)公共查詢機(jī)制,x.500目錄可自動(dòng)完成這一存儲(chǔ)過程。影響企業(yè)普遍接受p ki的一大障礙是不同ca之間的交叉認(rèn)證。假設(shè)有兩家公司,每一家企業(yè)分別使用來自不同供應(yīng)商的ca,現(xiàn)在它們希望相互托管一段時(shí)間。如果其后援?dāng)?shù)據(jù)庫(kù)支持交叉認(rèn)證, 則這兩家企業(yè)顯然可以互相托管它們的ca,因而它們所托管的所有用戶均可由兩家企業(yè)的ca所托管。
* 認(rèn)證機(jī)關(guān)
ca是證書的簽發(fā)機(jī)構(gòu),它是pki的核心。眾所周知,構(gòu)建密碼服務(wù)系統(tǒng)的核心內(nèi)容是如何實(shí)現(xiàn)密鑰管理,公鑰體制涉及到一對(duì)密鑰,即私鑰和公鑰, 私鑰只由持有者秘密掌握,無須在網(wǎng)上傳送,而公鑰是公開的,需要在網(wǎng)上傳送,故公鑰體制的密鑰管理主要是公鑰的管理問題,目前較好的解決方案是引進(jìn)證書(certificate)機(jī)制。
證書是公開密鑰體制的一種密鑰管理媒介。它是一種權(quán)威性的電子文檔,形同網(wǎng)絡(luò)計(jì)算環(huán)境中的一種身份證,用于證明某一主體(如人、服務(wù)器等)的身份以及其公開密鑰的合法性。在使用公鑰體制的網(wǎng)絡(luò)環(huán)境中, 必須向公鑰的使用者證明公鑰的真實(shí)合法性。因此,在公鑰體制環(huán)境中,必須有一個(gè)可信的機(jī)構(gòu)來對(duì)任何一個(gè)主體的公鑰進(jìn)行公證,證明主體的身份以及他與公鑰的匹配關(guān)系。c a正是這樣的機(jī)構(gòu),它的職責(zé)歸納起來有:
1、驗(yàn)證并標(biāo)識(shí)證書申請(qǐng)者的身份;
2、確保ca用于簽名證書的非對(duì)稱密鑰的質(zhì)量;
3、確保整個(gè)簽證過程的安全性,確保簽名私鑰的安全性;
4、證書材料信息(包括公鑰證書序列號(hào)、ca標(biāo)識(shí)等)的管理;
5、確定并檢查證書的有效期限;
6、確保證書主體標(biāo)識(shí)的唯一性,防止重名;
7、發(fā)布并維護(hù)作廢證書表;
8、對(duì)整個(gè)證書簽發(fā)過程做日志記錄;
9、向申請(qǐng)人發(fā)通知。
其中最為重要的是ca自己的一對(duì)密鑰的管理,它必須確保其高度的機(jī)密性,防止他方偽造證書。ca的公鑰在網(wǎng)上公開,整個(gè)網(wǎng)絡(luò)系統(tǒng)必須保證完整性。
* 證書庫(kù)
證書庫(kù)是證書的集中存放地,它與網(wǎng)上"白頁(yè)”類似,是網(wǎng)上的一種公共信息庫(kù),用戶可以從此處獲得其他用戶的證書和公鑰。
構(gòu)造證書庫(kù)的最佳方法是采用支持ldap協(xié)議的目錄系統(tǒng),用戶或相關(guān)的應(yīng)用通過ldap來訪問證書庫(kù)。系統(tǒng)必須確保證書庫(kù)的完整性,防止偽造、篡改證書。
* 密鑰備份及恢復(fù)系統(tǒng)
* 證書作廢處理系統(tǒng)
* pki應(yīng)用接口系統(tǒng)
pki的價(jià)值在于使用戶能夠方便地使用加密、數(shù)字簽名等安全服務(wù),因此一個(gè)完整的pki必須提供良好的應(yīng)用接口系統(tǒng),使得各種各樣的應(yīng)用能夠以安全、一致、可信的方式與p ki交互,確保所建立起來的網(wǎng)絡(luò)環(huán)境的可信性,同時(shí)降低管理維護(hù)成本。最后,pki應(yīng)用接口系統(tǒng)應(yīng)該是跨平臺(tái)的。
許多權(quán)威的認(rèn)證方案供應(yīng)商(例如verisign、thawte以及gte)目前都在提供外包的pki。外包pki最大的問題是,用戶必須把企業(yè)托管給某一服務(wù)提供商, 即讓出對(duì)網(wǎng)絡(luò)安全的控制權(quán)。如果不愿這樣做,則可建造一個(gè)專用的pki。專用方案通常需把來自entrust、baltimore technologies以及xcert的多種服務(wù)器產(chǎn)品與來自主流應(yīng)用程序供應(yīng)商(如microsoft、netscape以及qualcomm)的產(chǎn)品組合在一起。專用pk i還要求企業(yè)在準(zhǔn)備其基礎(chǔ)設(shè)施的過程中投入大量的財(cái)力與物力。
7.jaas
擴(kuò)展jaas實(shí)現(xiàn)類實(shí)例級(jí)授權(quán)
“java 認(rèn)證和授權(quán)服務(wù)”(java authentication and authorization service,jaas)
在 jaas 下,可以給予用戶或服務(wù)特定的許可權(quán)來執(zhí)行 java 類中的代碼。在本文中,軟件工程師 carlos fonseca 向您展示如何為企業(yè)擴(kuò)展 jaas 框架。向 jaas 框架添加類實(shí)例級(jí)授權(quán)和特定關(guān)系使您能夠構(gòu)建更動(dòng)態(tài)、更靈活并且伸縮性更好的企業(yè)應(yīng)用程序。
大多數(shù) java 應(yīng)用程序都需要某種類實(shí)例級(jí)的訪問控制。例如,基于 web 的、自我服務(wù)的拍賣應(yīng)用程序的規(guī)范可能有下列要求:
任何已注冊(cè)(經(jīng)過認(rèn)證)的用戶都可以創(chuàng)建一個(gè)拍賣,但只有創(chuàng)建拍賣的用戶才可以修改這個(gè)拍賣。
這意味著任何用戶都可以執(zhí)行被編寫用來創(chuàng)建 auction 類實(shí)例的代碼,但只有擁有該實(shí)例的用戶可以執(zhí)行用來修改它的代碼。通常情況下,創(chuàng)建 auction 實(shí)例的用戶就是所有者。這被稱為類實(shí)例所有者關(guān)系(class instance owner relationship)。
該應(yīng)用程序的另一個(gè)要求可能是:
任何用戶都可以為拍賣創(chuàng)建一個(gè)投標(biāo),拍賣的所有者可以接受或拒絕任何投標(biāo)。
再一次,任何用戶都可以執(zhí)行被編寫用來創(chuàng)建 bid 類實(shí)例的代碼,但只有擁有該實(shí)例的用戶會(huì)被授予修改該實(shí)例的許可權(quán)。而且,auction 類實(shí)例的所有者必須能夠修改相關(guān)的 bid 類實(shí)例中的接受標(biāo)志。這意味著在 auction 實(shí)例和相應(yīng)的 bid 實(shí)例之間有一種被稱為特定關(guān)系(special relationship)的關(guān)系。
不幸的是,“java 認(rèn)證和授權(quán)服務(wù)”(jaas)— 它是 java 2 平臺(tái)的一部分 — 沒有考慮到類實(shí)例級(jí)訪問控制或者特定關(guān)系。在本文中,我們將擴(kuò)展 jaas 框架使其同時(shí)包含這兩者。推動(dòng)這種擴(kuò)展的動(dòng)力是允許我們將訪問控制分離到一個(gè)通用的框架,該框架使用基于所有權(quán)和特定關(guān)系的策略。然后管理員可以在應(yīng)用程序的生命周期內(nèi)更改這些策略。
在深入到擴(kuò)展 jaas 框架之前,我們將重溫一下 java 2 平臺(tái)的訪問控制機(jī)制。我們將討論策略文件和許可權(quán)的使用,并討論 securitymanager 和 accesscontroller 之間的關(guān)系。
java 2 平臺(tái)中的訪問控制
在 java 2 平臺(tái)中,所有的代碼,不管它是本地代碼還是遠(yuǎn)程代碼,都可以由策略來控制。策略(policy)由不同位置上的代碼的一組許可權(quán)定義,或者由不同的簽發(fā)者定義、或者由這兩者定義。許可權(quán)允許對(duì)資源進(jìn)行訪問;它通過名稱來定義,并且可能與某些操作關(guān)聯(lián)在一起。
抽象類 java.security.policy 被用于表示應(yīng)用程序的安全性策略。缺省的實(shí)現(xiàn)由 sun.security.provider.policyfile 提供,在 sun.security.provider.policyfile 中,策略被定義在一個(gè)文件中。清單 1 是一個(gè)典型策略文件示例:
清單 1. 一個(gè)典型的策略文件
// grant these permissions to code loaded from a sample.jar file
// in the c drive and if it is signed by xyz
grant codebase "file:/c:/sample.jar", signedby "xyz" {
// allow socket actions to any host using port 8080
permission java.net.socketpermission "*:8080", "accept, connect,
listen, resolve";
// allows file access (read, write, execute, delete) in
// the user's home directory.
permission java.io.filepermission "${user.home}/-", "read, write,
execute, delete";
};
securitymanager 對(duì) accesscontroller
在標(biāo)準(zhǔn) jdk 分發(fā)版中,控制代碼源訪問的機(jī)制缺省情況下是關(guān)閉的。在 java 2 平臺(tái)以前,對(duì)代碼源的訪問都是由 securitymanager 類管理的。securitymanager 是由 java.security.manager 系統(tǒng)屬性啟動(dòng)的,如下所示:
java -djava.security.manager
在 java 2 平臺(tái)中,可以將一個(gè)應(yīng)用程序設(shè)置為使用 java.lang.securitymanager 類或者 java.security.accesscontroller 類管理敏感的操作。accesscontroller 在 java 2 平臺(tái)中是新出現(xiàn)的。為便于向后兼容,securitymanager 類仍然存在,但把自己的決定提交 accesscontroller 類裁決。securitymanager 和 accesscontroller 都使用應(yīng)用程序的策略文件確定是否允許一個(gè)被請(qǐng)求的操作。清單 2 顯示了 accesscontroller 如何處理 socketpermission 請(qǐng)求:
清單 2. 保護(hù)敏感操作
public void somemethod() {
permission permission=
new java.net.socketpermission("localhost:8080", "connect");
accesscontroller.checkpermission(permission);
// sensitive code starts here
socket s=new socket("localhost", 8080);
}
在這個(gè)示例中,我們看到 accesscontroller 檢查應(yīng)用程序的當(dāng)前策略實(shí)現(xiàn)。如果策略文件中定義的任何許可權(quán)暗示了被請(qǐng)求的許可權(quán),該方法將只簡(jiǎn)單地返回;否則拋出一個(gè) accesscontrolexception 異常。在這個(gè)示例中,檢查實(shí)際上是多余的,因?yàn)槿笔√捉幼謱?shí)現(xiàn)的構(gòu)造函數(shù)也執(zhí)行相同的檢查。
在下一部分,我們將更仔細(xì)地看一下 accesscontroller 如何與 java.security.policy 實(shí)現(xiàn)共同合作安全地處理應(yīng)用程序請(qǐng)求。
運(yùn)行中的 accesscontroller
accesscontroller 類典型的 checkpermission(permission p) 方法調(diào)用可能會(huì)導(dǎo)致下面的一系列操作:
accesscontroller 調(diào)用 java.security.policy 類實(shí)現(xiàn)的 getpermissions(codesource codesource) 方法。
getpermissions(codesource codesource) 方法返回一個(gè) permissioncollection 類實(shí)例,這個(gè)類實(shí)例代表一個(gè)相同類型許可權(quán)的集合。
accesscontroller 調(diào)用 permissioncollection 類的 implies(permission p) 方法。
接下來,permissioncollection 調(diào)用集合中包含的單個(gè) permission 對(duì)象的 implies(permission p) 方法。如果集合中的當(dāng)前許可權(quán)對(duì)象暗示指定的許可權(quán),則這些方法返回 true,否則返回 false。
現(xiàn)在,讓我們更詳細(xì)地看一下這個(gè)訪問控制序列中的重要元素。
permissioncollection 類
大多數(shù)許可權(quán)類類型都有一個(gè)相應(yīng)的 permissioncollection 類。這樣一個(gè)集合的實(shí)例可以通過調(diào)用 permission 子類實(shí)現(xiàn)定義的 newpermissioncollection() 方法來創(chuàng)建。java.security.policy 類實(shí)現(xiàn)的 getpermissions() 方法也可以返回 permissions 類實(shí)例 — permissioncollection 的一個(gè)子類。這個(gè)類代表由 permissioncollection 組織的不同類型許可權(quán)對(duì)象的一個(gè)集合。permissions 類的 implies(permission p) 方法可以調(diào)用單個(gè) permissioncollection 類的 implies(permission p) 方法。
codesource 和 protectiondomain 類
許可權(quán)組合與 codesource(被用于驗(yàn)證簽碼(signed code)的代碼位置和證書)被封裝在 protectiondomain 類中。有相同許可權(quán)和相同 codesource 的類實(shí)例被放在相同的域中。帶有相同許可權(quán),但不同 codesource 的類被放在不同的域中。一個(gè)類只可屬于一個(gè) protectiondomain。要為對(duì)象獲取 protectiondomain,請(qǐng)使用 java.lang.class 類中定義的 getprotectiondomain() 方法。
許可權(quán)
賦予 codesource 許可權(quán)并不一定意味著允許所暗示的操作。要使操作成功完成,調(diào)用棧中的每個(gè)類必須有必需的許可權(quán)。換句話說,如果您將 java.io.filepermission 賦給類 b,而類 b 是由類 a 來調(diào)用,那么類 a 必須也有相同的許可權(quán)或者暗示 java.io.filepermission 的許可權(quán)。
在另一方面,調(diào)用類可能需要臨時(shí)許可權(quán)來完成另一個(gè)擁有那些許可權(quán)的類中的操作。例如,當(dāng)從另一個(gè)位置加載的類訪問本地文件系統(tǒng)時(shí),我們可能不信任它。但是,本地加載的類被授予對(duì)某個(gè)目錄的讀許可權(quán)。這些類可以實(shí)現(xiàn) privilegedaction 接口來給予調(diào)用類許可權(quán)以便完成指定的操作。調(diào)用棧的檢查在遇到 privilegedaction 實(shí)例時(shí)停止,有效地將執(zhí)行指定操作所必需的許可權(quán)授予所有的后繼類調(diào)用。
使用 jaas
顧名思義,jaas 由兩個(gè)主要組件組成:認(rèn)證和授權(quán)。我們主要關(guān)注擴(kuò)展 jaas 的授權(quán)組件,但開始我們先簡(jiǎn)要概述一下 jaas 認(rèn)證,緊接著看一下一個(gè)簡(jiǎn)單的 jaas 授權(quán)操作。
jaas 中的用戶認(rèn)證
jaas 通過添加基于 subject 的策略加強(qiáng)了 java 2 中定義的訪問控制安全性模型。許可權(quán)的授予不僅基于 codesource,還基于執(zhí)行代碼的用戶。顯然,要使這個(gè)模型生效,每個(gè)用戶都必須經(jīng)過認(rèn)證。
jaas 的認(rèn)證機(jī)制建立在一組可插登錄模塊的基礎(chǔ)上。jaas 分發(fā)版包含幾個(gè) loginmodule 實(shí)現(xiàn)。loginmodules 可以用于提示用戶輸入用戶標(biāo)識(shí)和密碼。logincontext 類使用一個(gè)配置文件來確定使用哪個(gè) loginmodule 對(duì)用戶進(jìn)行認(rèn)證。這個(gè)配置可以通過系統(tǒng)屬性 java.security.auth.login.config 指定。一個(gè)示例配置是:
java -djava.security.auth.login.config=login.conf
下面是一個(gè)登錄配置文件的樣子:
example {
com.ibm.resource.security.auth.loginmoduleexample required
debug=true userfile="users.xml" groupfile="groups.xml";
};
認(rèn)識(shí)您的主體
subject 類被用于封裝一個(gè)被認(rèn)證實(shí)體(比如用戶)的憑證。一個(gè) subject 可能擁有一個(gè)被稱為主體(principal)的身份分組。例如,如果 subject 是一個(gè)用戶,用戶的名字和相關(guān)的社會(huì)保險(xiǎn)號(hào)可能是 subject 的某些身份或主體。主體是與身份名關(guān)聯(lián)在一起的。
principal 實(shí)現(xiàn)類及其名稱都是在 jaas 策略文件中指定的。缺省的 jaas 實(shí)現(xiàn)使用的策略文件與 java 2 實(shí)現(xiàn)的策略文件相似 — 除了每個(gè)授權(quán)語(yǔ)句必須與至少一個(gè)主體關(guān)聯(lián)在一起。javax.security.auth.policy 抽象類被用于表示 jaas 安全性策略。它的缺省實(shí)現(xiàn)由 com.sun.security.auth.policyfile 提供,在 com.sun.security.auth.policyfile 中策略定義在一個(gè)文件中。清單 3 是 jaas 策略文件的一個(gè)示例:
清單 3. 示例 jaas 策略文件
// example grant entry
grant codebase "file:/c:/sample.jar", signedby "xyz",
principal com.ibm.resource.security.auth.principalexample "admin" {
// allow socket actions to any host using port 8080
permission java.net.socketpermission
"*:8080", "accept, connect, listen, resolve";
// allows file access (read, write, execute, delete) in
// the user's home directory.
permission java.io.filepermission
"${user.home}/-", "read, write, execute, delete";
};
這個(gè)示例與清單 1 中所示的標(biāo)準(zhǔn) java 2 策略文件相似。實(shí)際上,唯一的不同是主體語(yǔ)句,該語(yǔ)句聲明只有擁有指定主體和主體名字的 subject(用戶)被授予指定的許可權(quán)。
再一次,使用系統(tǒng)屬性 java.security.auth.policy 指出 jaas 策略文件駐留在何處,如下所示:
java -djava.security.auth.policy=policy.jaas
subject 類包含幾個(gè)方法來作為特殊 subject 執(zhí)行工作;這些方法如下所示:
public static object
doas(subject subject, java.security.privilegedaction action)
public static object
doas(subject subject, java.security.privilegedaction action)
throws java.security.privilegedactionexception
注意,用來保護(hù)敏感代碼的方法與“java 2 代碼源訪問控制”(java 2 codesource access control)概述中描述的方法相同。請(qǐng)參閱參考資料部分以了解更多關(guān)于 jaas 中代碼源訪問控制和認(rèn)證的信息。
jaas 中的授權(quán)
清單 4 顯示一個(gè)授權(quán)請(qǐng)求的結(jié)果,該請(qǐng)求使用清單 3 中顯示的 jaas 策略文件。假設(shè)已經(jīng)安裝了 securitymanager,并且 logincontext 已經(jīng)認(rèn)證了一個(gè)帶有名為“admin”的 com.ibm.resource.security.auth.principalexample 主體的 subject。
清單 4. 一個(gè)簡(jiǎn)單的授權(quán)請(qǐng)求
public class jaasexample {
public static void main(string[] args) {
...
// where authenticateduser is a subject with
// a principalexample named admin.
subject.doas(authenticateduser, new jaasexampleaction());
...
}
}
public class jaasexampleaction implements privilegedaction {
public object run() {
filewriter fw=new filewriter("hi.txt");
fw.write("hello, world!");
fw.close();
}
}
這里,敏感代碼被封裝在 jaasexampleaction 類中。還要注意,調(diào)用類不要求為 jaasexampleaction 類代碼源授予許可權(quán),因?yàn)樗鼘?shí)現(xiàn)了一個(gè) privilegedaction。
擴(kuò)展 jaas
大多數(shù)應(yīng)用程序都有定制邏輯,它授權(quán)用戶不僅僅在類上執(zhí)行操作,而且還在該類的實(shí)例上執(zhí)行操作。這種授權(quán)通常建立在用戶和實(shí)例之間的關(guān)系上。這是 jaas 的一個(gè)小缺點(diǎn)。然而,幸運(yùn)的是,這樣設(shè)計(jì) jaas 使得 jaas 可以擴(kuò)展。只要做一點(diǎn)工作,我們將可以擴(kuò)展 jaas,使其包含一個(gè)通用的、類實(shí)例級(jí)的授權(quán)框架。
在文章開頭處我已經(jīng)說明了,抽象類 javax.security.auth.policy 被用于代表 jaas 安全性策略。它的缺省實(shí)現(xiàn)是由 com.sun.security.auth.policyfile 類提供。policyfile 類從 jaas 格式的文件(象清單 3 中顯示的那個(gè)一樣)中讀取策略。
我們需要向這個(gè)文件添加一個(gè)東西為類實(shí)例級(jí)授權(quán)擴(kuò)展策略定義:一個(gè)與許可權(quán)語(yǔ)句相關(guān)的可選關(guān)系參數(shù)。
缺省 jaas 許可權(quán)語(yǔ)句的格式如下:
permission <permission implementation class>; [name], [actions];
我們?cè)谶@個(gè)許可權(quán)語(yǔ)句的末尾添加一個(gè)可選的關(guān)系參數(shù)來完成策略定義。下面是新許可權(quán)語(yǔ)句的格式:
permission <permission implementation class>;
[name], [actions], [relationship];
在為類實(shí)例級(jí)授權(quán)擴(kuò)展 jaas 時(shí)要注意的最重要的一點(diǎn)是:許可權(quán)實(shí)現(xiàn)類必須有一個(gè)帶三個(gè)參數(shù)的構(gòu)造函數(shù)。第一個(gè)參數(shù)是名稱參數(shù),第二個(gè)是行為參數(shù),最后一個(gè)是關(guān)系參數(shù)。
解析新文件格式
既然文件格式已經(jīng)改變,就需要一個(gè)新的 javax.security.auth.policy 子類來解析文件。
為簡(jiǎn)單起見,我們的示例使用了一個(gè)新的 javax.security.auth.policy 子類 com.ibm.resource.security.auth.xmlpolicyfile,來從 xml 文件讀取策略。在實(shí)際的企業(yè)應(yīng)用程序中,關(guān)系數(shù)據(jù)庫(kù)更適合執(zhí)行這個(gè)任務(wù)。
使用 xmlpolicyfile 類代替缺省的 jaas 訪問控制策略實(shí)現(xiàn)的最容易的方法是向 java.security 屬性文件添加 auth.policy.provider=com.ibm.resource.security.auth.xmlpolicyfile 條目。java.security 屬性文件位于 java 2 平臺(tái)運(yùn)行時(shí)的 lib/security 目錄下。清單 5 是與 xmlpolicyfile 類一起使用的樣本 xml 策略文件:
清單 5. 一個(gè) xml 策略文件
<?xml version="1.0"?>;
<policy>;
<grant codebase="file:/d:/sample_actions.jar">;
<principal classname=
"com.ibm.resource.security.auth.principalexample" name="users">;
<permission classname=
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.auction"
actions="create" />;
<permission classname=
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.auction"
actions="read" />;
<permission classname=
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.auction"
actions="write"
relationship="owner" />;
<permission classname=
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.bid"
actions="create" />;
<permission classname=
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.bid"
actions="read" />;
<permission classname=
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.bid"
actions="write"
relationship="owner" />;
<permission classname=
"com.ibm.resource.security.auth.resourcepermission"
name="com.ibm.security.sample.bid"
actions="accept"
relationship="actionowner" />;
</principal>;
</grant>;
</policy>;
在這個(gè)示例策略文件中,任何與名為 principalexample 的用戶有關(guān)的用戶(subject)都可以創(chuàng)建并讀取一個(gè) auction.class 實(shí)例。但是,只有創(chuàng)建該實(shí)例的用戶才可以更新(寫)它。這是第三個(gè) permission 元素定義的,該元素包含值為 owner 的 relationship 屬性。bid.class 實(shí)例也是一樣,除了相應(yīng) auction.class 實(shí)例的所有者可以更改投標(biāo)接受標(biāo)志。
resource 接口
要求類實(shí)例級(jí)訪問控制的類必須實(shí)現(xiàn) resource 接口。該接口的 getowner() 方法返回類實(shí)例的所有者。fulfills(subject subject, string relationship) 方法被用于處理特定關(guān)系。另外,這些類使用 com.ibm.resource.security.auth.resourcepermission 類保護(hù)敏感代碼。例如,auction 類擁有下列構(gòu)造函數(shù):
public auction() {
permission permission=
new resourcepermission("com.ibm.security.sample.auction", "create");
accesscontroller.checkpermission(permission);
}
所有者關(guān)系
resourcepermission 類的 implies(permission p) 方法是這個(gè)框架的關(guān)鍵。implies() 方法就等同性比較名稱和行為屬性。如果定義了一個(gè)關(guān)系,那么必須把受保護(hù)的類實(shí)例(resource)傳遞到 resourcepermission 構(gòu)造函數(shù)中。resourcepermission 類理解所有者關(guān)系。它將類實(shí)例的所有者與執(zhí)行代碼的 subject(用戶)進(jìn)行比較。特定關(guān)系被委托給受保護(hù)類的 fulfills() 方法。
例如,在清單 5 中所示的 xml 策略文件中,只有 auction 類實(shí)例的所有者可以更新(寫)文件。該類的 setter 方法使用清單 6 中顯示的保護(hù)代碼:
清單 6. 運(yùn)行中的 implies(permission) 方法
public void setname(string newname) {
permission permission=
new resourcepermission("com.ibm.security.sample.auction", "write", this);
accesscontroller.checkpermission(permission);
// sensitive code
this.name=newname;
}
被傳遞到 resourcepermission 構(gòu)造函數(shù)中的 this 引用代表 auction 類實(shí)現(xiàn)的 resource 接口。由于策略文件中列出的關(guān)系是 owner,所以 resourcepermission 類使用這個(gè)引用檢查當(dāng)前 subject(用戶)是否擁有與實(shí)例所有者相匹配的主體。如果指定了另一個(gè)關(guān)系,那么 resourcepermission 類調(diào)用 auction 類的 fulfills(subject subject, string relationship) 方法。由 resource 實(shí)現(xiàn)類提供 fulfills() 方法中的邏輯。
xml 策略文件中列出的 bid 類擁有清單 7 中所示的方法(假設(shè) bid 類實(shí)例有一個(gè)對(duì)相應(yīng) auction 類實(shí)例的引用 — auction)。
清單 7. 處理特定關(guān)系
public void setaccepted(boolean flag) {
permission permission=
new resourcepermission("com.ibm.security.sample.auction", "accept", this);
accesscontroller.checkpermission(permission);
// sensitive code
this.accepted=flag;
}
public boolean fulfills(subject user, string relationship) {
if( relationship.equalsignorecase("auctionowner") ) {
string auctionowner=auction.getowner();
iterator principaliterator=user.getprincipals().iterator();
while(principaliterator.hasnext()) {
principal principal=(principal) principaliterator.next();
if( principal.getname().equals(auctionowner) )
return true;
}
}
return false;
}
傳遞到 fulfills() 方法中的關(guān)系字符串是策略文件中列出的關(guān)系。在這個(gè)案例中,我們使用了“auctionowner”字符串。
缺省情況下,xmlpolicyfile 類在當(dāng)前工作目錄中查找名為 resourcepolicy.xml 的文件。系統(tǒng)屬性 com.ibm.resource.security.auth.policy 可以用于指定另一個(gè)不同的文件名和位置。
websphere application server 示例
除命令行示例之外,您可能還想運(yùn)行這個(gè)簡(jiǎn)單的程序,該程序?yàn)榱?ibm websphere application server,version 4.0.2 而被優(yōu)化。
一個(gè)可運(yùn)行的示例
綜合這些信息,我們將運(yùn)行一個(gè)簡(jiǎn)單的命令行示例。該示例程序包含三個(gè) jar 文件:
resourcesecurity.jar
example.jar
exampleactions.jar
resourcesecurity.jar 文件包含允許實(shí)例級(jí)訪問控制的 jaas 擴(kuò)展框架。它還包含一個(gè) loginmoduleexample 類,這個(gè)類從 xml 文件讀取用戶認(rèn)證信息。用戶標(biāo)識(shí)和密碼存儲(chǔ)在 users.xml 文件中。用戶組存儲(chǔ)在 groups.xml 文件中。關(guān)于 loginmoduleexample 的更多信息,請(qǐng)參閱參考資料部分。
該示例包含四個(gè)附加的文件:
login.conf
policy
resourcepolicy.xml
run.bat
在試圖運(yùn)行這個(gè)示例程序之前,請(qǐng)確保更新了 run.bat、policy 和 resourcepolicy.xml 文件中的路徑。缺省情況下,所有的密碼都是“passw0rd”。
示例如何工作
該示例程序提示輸入用戶標(biāo)識(shí)和密碼。它用 users.xml 文件中的條目核對(duì)所提供的用戶標(biāo)識(shí)和密碼。在認(rèn)證了用戶之后,程序設(shè)法創(chuàng)建一個(gè) userprofile 類實(shí)例,修改它并從中讀取。缺省情況下,userprofile 類的所有者是 jane(jane)。當(dāng) jane 登錄時(shí),三個(gè)操作全部成功。當(dāng) john(john)登錄時(shí),只有創(chuàng)建操作成功。當(dāng) jane 的經(jīng)理 lou(lou)登錄時(shí),只有第一個(gè)和最后一個(gè)操作成功。當(dāng)系統(tǒng)管理員(admin)登錄時(shí),操作全部成功。當(dāng)然,只有當(dāng)提供的 resourcepolicy.xml 文件未被修改時(shí),上述這些才都是真的。
示例安裝
下面的安裝指導(dǎo)假設(shè)您正在使用 jdk 1.3 并且已經(jīng)把文件解壓縮到 d:jaasexample 目錄。通過將文件解壓縮到這個(gè)目錄,您可以省去一些工作;否則您就必須使用正確的路徑名修改 policy 和 resourcesecurity.xml 策略文件。
下面是運(yùn)行該示例需要做的工作:
下載這個(gè)示例的源文件。
把 jaas.jar 和 jaasmod.jar 復(fù)制到 jdk jrelibext 目錄(即 d:jdk1.3jrelibext)。
向位于 jdk 的 jrelibsecurity 目錄(即 d:jdk1.3jrelibsecurity)中的 java.security 文件的末尾添加下面的字符串:auth.policy.provider=com.ibm.resource.security.auth.xmlpolicyfile。
執(zhí)行 run.bat 文件。
結(jié)束語(yǔ)
類實(shí)例級(jí)授權(quán)把訪問控制分離到一個(gè)通用框架(該框架使用基于所有權(quán)和特定關(guān)系的策略)中。然后管理員可以在應(yīng)用程序的生命周期內(nèi)更改這些策略。用這種方法擴(kuò)展 jaas 減少了您或另一個(gè)程序員必須在應(yīng)用程序生命周期內(nèi)業(yè)務(wù)規(guī)則發(fā)生更改時(shí)重寫代碼的可能性。
通過將關(guān)系字符串抽象為類可以進(jìn)一步擴(kuò)展特定關(guān)系這個(gè)概念。不調(diào)用 resource 實(shí)現(xiàn)類的 fulfills(subject user, string relationship) 方法,而只要調(diào)用 relationship 實(shí)現(xiàn)類中定義的新 fulfills(subject user, resource resource) 方法。這樣就會(huì)允許許多 resource 實(shí)現(xiàn)類使用相同的關(guān)系邏輯。
6.java的安全性
1. the security manager是一個(gè)application-wide object ( java.lang.securitymanager)
每個(gè)java application都可以有自己地security manager,但是默認(rèn)地java application沒有一個(gè)security manager
可以通過下面地代碼得到一個(gè)security manager
try
{
system.setsecuritymanager(new securitymanager(“--”));
}
catch( )
{}
2.
jdbc
在 jdbc 2 開發(fā)的過程中,sql99 還處在一種變化不定的情況下,F(xiàn)在規(guī)范已經(jīng)完成了,而且數(shù)據(jù)庫(kù)廠商已經(jīng)采用了部分標(biāo)準(zhǔn)。所以自然地,jdbc 規(guī)范就跟著將自己與 sql99 功能的一部分相統(tǒng)一。最新的 jdbc 規(guī)范已經(jīng)采用了 sql99 標(biāo)準(zhǔn)中那些已經(jīng)被廣泛支持的功能,還有那些在五年內(nèi)可能會(huì)獲得支持的功能。
1. datasource
在jdbc2.0 optional package中,提供了透明的連接池(connection pooling)。
一旦配置了j2ee應(yīng)用服務(wù)器后,只要用datasource獲取連接(connection),連接池(connection pooling)就會(huì)自動(dòng)的工作。
如果用戶希望建立一個(gè)數(shù)據(jù)庫(kù)連接,通過查詢?cè)趈ndi服務(wù)中的datasource,可以從datasource中獲取相應(yīng)的數(shù)據(jù)庫(kù)連接。
datasource被認(rèn)為是從jndi中獲取的網(wǎng)絡(luò)資源。
datasource在池中保存的對(duì)象都實(shí)現(xiàn)了pooledconnection接口。
當(dāng)應(yīng)用程序向datasource請(qǐng)求一個(gè)connection時(shí),它會(huì)找到一個(gè)可用的pooledconnection對(duì)象。
如果連接池空了,它就向connectionpoolecdatasource請(qǐng)求一個(gè)新的pooledconnection對(duì)象
通過使用 datasource 接口 (jdbc 2.0) 或 drivermanager (jdbc 1.0) 接口,j2ee 組件可以獲得物理數(shù)據(jù)庫(kù)連接對(duì)象(connection)。要獲得邏輯(合用的)連接,j2ee 組件必須使用以下這些 jdbc 2.0 合用管理器接口:
javax.sql.connectionpooldatasource 接口,該接口充當(dāng)合用的 java.sql.connection 對(duì)象的資源管理器連接 factory。每家數(shù)據(jù)庫(kù)服務(wù)器供應(yīng)商都提供該接口的實(shí)現(xiàn)
(例如,oracle 實(shí)現(xiàn) oracle.jdbc.pool.oracleconnectionpooldatasource 類)。
javax.sql.pooledconnection 接口,該接口封裝到數(shù)據(jù)庫(kù)的物理連接。同樣,數(shù)據(jù)庫(kù)供應(yīng)商提供其實(shí)現(xiàn)。
對(duì)于那些接口和 xa 連接的每一個(gè),都存在一個(gè) xa(x/open 規(guī)范)等價(jià)定義。
2. resultset
在jdbc2.0中,為了獲得一個(gè)uptatable result,在query語(yǔ)句里必須包含primarykey,并且查詢的內(nèi)容里必須來自一個(gè)table
ava.sql.resultset接口中定義了三種類型的結(jié)果集
type_forward_only
type_scroll_insensitive 這種類型的結(jié)果集支持雙向滾動(dòng)
type_scroll_sensitive
如果要建立一個(gè)雙向滾動(dòng)的resultset,一定要在建立statement的時(shí)候使用如下參數(shù)
statement stmt=conn.createstatement(resultset.type_scroll_insensitive,
resultset.concur_read_only);
3. jdbc驅(qū)動(dòng)程序
連通oracle8.1.6的jdbc
把oracle8.1.6/lib/jdbc/*.zip copy 到 %java_home%/jre/lib/ext/*.jar
如果光copy不ren為.jar是沒有用的。
4. 事務(wù)處理
本地事務(wù)
java.sql.connection接口可以控制事務(wù)邊界(即開始和結(jié)束)。
在事務(wù)開始的時(shí)候調(diào)用setautocommit( false ), 而在中止事務(wù)時(shí)調(diào)用rollback或commit()方法。這類事務(wù)叫本地事務(wù)。
分布式事務(wù)
但是,在特定的情況下,可能有多個(gè)客戶(例如兩個(gè)不同的servlet或ejb組件)參與了同一個(gè)事務(wù)。
或者,客戶在同一個(gè)事務(wù)中可能會(huì)執(zhí)行跨越多個(gè)數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)操作。
jdbc2.0 optional package 同jta一起來實(shí)現(xiàn)分布式樣事務(wù)。
5. 一些技巧
檢索自動(dòng)產(chǎn)生的關(guān)鍵字
為了解決對(duì)獲取自動(dòng)產(chǎn)生的或自動(dòng)增加的關(guān)鍵字的值的需求,jdbc 3.0 api 現(xiàn)在將獲取這種值變得很輕松。要確定任何所產(chǎn)生的關(guān)鍵字的值,只要簡(jiǎn)單地在語(yǔ)句的 execute() 方法中指定一個(gè)可選的標(biāo)記,表示您有興趣獲取產(chǎn)生的值。您感興趣的程度可以是 statement.return_generated_keys,也可以是 statement.no_generated_keys。在執(zhí)行這條語(yǔ)句后,所產(chǎn)生的關(guān)鍵字的值就會(huì)通過從 statement 的實(shí)例方法 getgeneratedkeys() 來檢索 resultset 而獲得。resultset 包含了每個(gè)所產(chǎn)生的關(guān)鍵字的列。清單 1 中的示例創(chuàng)建一個(gè)新的作者并返回對(duì)應(yīng)的自動(dòng)產(chǎn)生的關(guān)鍵字。
清單 1. 檢索自動(dòng)產(chǎn)生的關(guān)鍵字
statement stmt=conn.createstatement();
// obtain the generated key that results from the query.
stmt.executeupdate("insert into authors " +
'(first_name, last_name) " +
"values ('george', 'orwell')",
statement.return_generated_keys);
resultset rs=stmt.getgeneratedkeys();
if ( rs.next() ) {
// retrieve the auto generated key(s).
int key=rs.getint();
}
jta/jts
1.jta/jts基本知識(shí)
服務(wù)器實(shí)現(xiàn)jts是否對(duì)應(yīng)用程序開發(fā)人員來說不是很重要的。
對(duì)你來說,應(yīng)該把jta看作是可用的api。
jta是用來開發(fā)distributed tansaction的 api.
而jts定義了支持jta中實(shí)現(xiàn)transaction manager 的規(guī)范。
javatransaction service (jts) specifies the implementation of a transaction manager which supports the java transaction api (jta) 1.0 specification at the high-level and implements the java mapping of the omg object transaction service (ots) 1.1 specification at the low-level. jts uses the standard corba orb/ts interfaces and internet inter-orb protocol (iiop) for transaction context propagation between jts transaction managers.
a jts transaction manager provides transaction services to the parties involved in distributed transactions: the application server, the resource manager, the standalone transactional application, and the communication resource manager (crm).
2.jta
1.1 事務(wù)處理的概念
jta實(shí)際上是由兩部分組成的:一個(gè)高級(jí)的事務(wù)性客戶接口和一個(gè)低級(jí)的 x/open xa接口。
我們關(guān)心的是高級(jí)客戶接口,因?yàn)閎ean可以訪問它,而且是推薦的客戶應(yīng)用程序的事務(wù)性接口。
低級(jí)的xa接口是由ejb服務(wù)器和容器使用來自動(dòng)協(xié)調(diào)事務(wù)和資源(如數(shù)據(jù)庫(kù))的
1.1.1事務(wù)劃分
a.程序劃分
使用usertransaction啟動(dòng)jta事務(wù)
the usertransaction interface defines the methods that allow an application to explicitly manage transaction boundaries.(from j2ee api document)
- 0
- 頂一下
《小學(xué)語(yǔ)文新課程標(biāo)準(zhǔn)》學(xué)習(xí)心得體會(huì)
《小學(xué)語(yǔ)文新課程標(biāo)準(zhǔn)》學(xué)習(xí)心得體會(huì)
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 yyfangchan@163.com (舉報(bào)時(shí)請(qǐng)帶上具體的網(wǎng)址) 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除