顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2010-11-29

Java EE Custom Authentication - j_security_check / j_username / j_password


Java EE 提供了 JSP/Servlet此種 Web Programming Model

在認證/授權 (AA, Authentication & Authorization) 的部分,係透過 Deployment Descriptor 採用宣告式的安全設定(Declarative Security)

然而,在Java EE 的規範當中,儘規範了如何定義角色、如何限制相關的功能(URL)可被何種角色存取

而沒有規範到實際的認證、授權如何進行? 使用者的帳號、密碼、角色 是存在哪裡 ?

實際的使用者資料庫(User Registry)是使用 DB? LDAP? File? OS? 哪一種...

在做 JSP 的 form authentication 時, 我們知道 login 頁面要有一個 form action 為 j_seurity_check, 帳號/密碼欄位名為 j_username、j_password,但是 開發人員不必做任何事情,Java EE Container 即會幫你完成後續的認證/授權相關事宜

實際上,因為Java EE沒有規範Container要如何實作認證授權,所以 每個Container所用的 User Registry可能都不一樣。如,Apache Tomcat 預設就是透過 tomcat-users.xml 這個檔案來儲存使用者的帳號、密碼。

有時候,我們已經有既有的 User Registry 或是 想要自已客製化實作認證/授權時,這時候,就要用到Container 提供的 Custom Registry 機制,來加以客制化。同樣的,因為此段在Java EE沒有規範到,所以是依各Container 的不同,而有不同的作法 (亦即,使用 Custom Registry的Application, 在更換Container時,可能有可攜性的問題要處理,需依新的Container的規定,額外實做Custom Registry的功能)

以 Tomcat 為例,預設是使用 「UserDatabaseRealm」(註: 所謂的Realm, 即用在儲存使用者認證/授權資訊的儲存庫, 即 前述的 User Registry),我們可以在 $CATALINA_BASE/conf/server.xml 此檔案裡,看到相關的宣告:

<resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml">

<realm classname="org.apache.catalina.realm.UserDatabaseRealm" resourcename="UserDatabase">

在Tomcat中,若要自訂其它種User Registry,可以參考官方的說明文件,基本上,它提供了六種管道:

- JDBCRealm
- DataSourceRealm
- JNDIRealm
- UserDatabaseRealm
- MemoryRealm
- JAASRealm

在 WebSphere 中,則是在Container透過 Custom Registry的設定,提供了LDAP、OS 及 自訂三種方法
在使用者自訂Registry的部分,只要實作 com.ibm.websphere.security.UserRegistry 這個介面,並在Container的設定中使用自行實作的 UserRegistry Class 即可~



閱讀全文...

2010-11-22

Axis2 與 .Net 1.1 Web Services 互通性問題


最近在實驗 Java Client to .Net Web Services 的互通性

Java 的部分,是使用 Apache 的 Axis 2

當我用 Axis 2 呼叫用 VS 2003 開發出來的 .Net 1.1 Web Services 時,總是會出現

Exception in thread "main" org.apache.axis2.AxisFault: Transport error: 404 Error: Not Found

百思不得其解,但使用 Axis 1 時,卻可正常呼叫

透過 WireShark 查知,Axis 2 在用 Http 傳送封包時,Transfer-Encoding 預設係使用 Http 1.1 規範裡新增的 Chunked Encoding 方式傳遞(HTTP Header -> Transfer-Encoding: chunked),而 Axis 1 則不使用 Chunked Encoding

因此,第一直覺,猜想是不是 IIS 的 metabase 設定中 ( C:\WINDOWS\system32\inetsrv\MetaBase.xml)AspEnableChunkedEncoding 這個設定值設成 FALSE 了? (Default 是 TRUE)

但 check 了一下,發現 IIS 有 enable Chunked Encoding

因此,就懷疑是不是 .Net Web Services 不直援 HTTP Chunked Encoding ?? 與用來開發的 .Net 版本有沒有關 ??

所以,就分別使用 VS 2003, 2005, 2008, 2010 製做 Web Services 來實驗

結果發現 不管 IIS 的 AspEnableChunkedEncoding 設定為何
VS 2003 開發出的 Web Services 是不能透過 Chunked Encoding 方式呼叫的
而 VS 2005 以上的版本開發出的 Web Services 則無此限制

因此,若使用 Axis 2 呼叫用 VS 2003 開發出的 Web Services 時,可以調整 Axis 2 呼叫時的參數,以正常呼叫 Web Services, 如下例(註: 我是使用 Axis2 預設的 "ADB Binding" -> XML to Object 的Binding方法啦):

Service1Stub stub = new Service1Stub(); stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
Service1Stub.HelloWorld hello = new Service1Stub.HelloWorld();
hello.setName("test");
System.out.println(stub.helloWorld(hello).getHelloWorldResult());

(註: 用 Eclipse 產生 Axis Web Services Client Project 時,目前預設是走 Axis 1, 若用 Axis2 附的 WSDL2Java 來產生 Web Services Stub 的話,則是走 Axis 2)

P.S. 這是我測試的結果啦~ 若大家有其它經驗 請再跟我分享 :)


閱讀全文...

2009-03-17

Tomcat Post / Get 中文編碼處理方法 (中文亂碼問題)


最近在把原本佈署在 Resin 的 Java Web Application移植到 Tomcat 時,有許多原本正常的中文get / post 功能,都變的異常,只要是透過 get / post 得到的資料,就會變亂碼

剛好也驗證了 Resin 在Character Encoding的部分做的較好
而看看網路上大家的問題,也可以知道 Tomcat 在編碼處理的部分 真是讓很多人頭痛

主要的原因是,TOMCAT 預設都是用 ISO-8859-1 的編碼方式來傳遞資訊

這個問題,可以解決的方式整理如下:

1. JSP 頁面的編碼宣告需與實際儲存檔案時用的編碼一致

這是個很好玩的問題~ 有些人 在頁面宣告用 big5 or UTF-8 or... 字集
但是,檔案實際儲存的方式與該編碼不同,則 頁面當然會出現亂碼的問題

2. 自行轉碼
form method=POST or GET 時 因為Tomcat預設編碼是ISO-8859-1的關係
直接用 <%=request.getParameter("firstname")%> 取值,中文字會變亂碼
(你傳的明明是UTF-8, 但是讀取時 確用 ISO-8859-1來解譯.. 當然有問題囉)
要使用 <%=new String(request.getParameter("firstname").getBytes( "ISO-8859-1"), "UTF-8")%>這種方式 來轉換編碼才會正常 (假設,頁面用的編碼為UTF-8時)

3. 透過設定 server.xml URIEncoding的方式 來處理 GET 亂碼問題
在 tomcat 的設定檔內 ./conf/server.xml 修改下列設定的話,則透過GET的方式傳遞參數
的話,Tomcat會用你指定的編碼方式來對待用get方法傳遞的參數,而不是使用預設的ISO-8859-1 (get 的方式是透過 url parameter傳遞參數)
但是,因為只處理 URIEncoding, 所以若使用 Post 傳遞,還是會有問題


URIEncoding: This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

P.S. 若使用 GET Method, 且設定了URIEncoding 的話就不用再做上述二的自行轉碼動作,如果多加該處理,一樣會有亂碼的問題

4. 使用 request.setCharacterEncoding 來處理 GET / POST 的亂碼問題
在處理的頁面,加上下列的處理即可,明確的告訴Tomcat request的編碼為何,不要一廂情願的使用ISO-8859-1來解讀~

<%request.setCharacterEncoding("UTF-8");%>

javax.servlet.servletRequest.setCharacterEncoding(string env)
Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader(). Otherwise, it has no effect.

5. 使用 filter 來處理 GET / POST 的亂碼問題
這個方法是最方便的,只要在 web.xml 裡面 透過 filter 的設定,讓每個網頁都能
透過 filter 的處理一體適用所有編碼問題的解決
方法如下:

a. 目前 Tomcat 提供的範例裡面,就有現成的 Encoding Filter, 位置如下:
.\Tomcat 6.0\webapps\examples\WEB-INF\classes\filters\SetCharacterEncodingFilter.class

b. 所以,只要把該 class 檔,copy 到你的 web application 的
.\WEB-INF\classes\filter 下,再搭配 web.xml 的filter 設定,
就可以讓所有符合 url pattern 的網頁,都能自動apply所想要的編碼設定(透過 encoding這個 parameter來設定),是不是很方便呢 ?
(這個功能 就像是自動把上述第四點的 setCharacterEncoding 語句 自動apply到各頁面囉)



------------
以上~ 就從 Resin Porting 到 Tomcat 的經驗,當然是使用 filter 的方式 一次解決~ 不然的話 就得每個網頁每個網頁去改囉~

延伸資料:
FAQ/CharacterEncoding
http://jim.blogsome.com/2005/05/27/jsp-chinese-character-solution/
http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=752


閱讀全文...

2009-02-18

IIS6 + Tomcat6 設定方法


1. 先有IIS

2. 安裝JDK
- download JDK and install
- set JAVA_HOME 環境變數至 jdk 安裝目錄

3. 安裝 Tomcat
- download Tomcat and install
- set CATALINA_HOME 環境變數至 Tomcat 安裝目錄

a. 首先先依上述連結下載取得 isapi_redirect-1.2.27.dll (目前最新版本)
b. 將該dll置於一特定目錄 (如: c:\TomcatConnector)
c. 在該目錄下 建立三個config file 分別為
isapi_redirect-1.2.27.properties (主檔名與 isapi_redirectxxxx.dll 的主檔名同)
workers.properties
uriworkermap.properties
d. 下述是我針對三個檔案的設定 (可在tomcat網站看到how-to說明及這些檔案的定義)
基本上,除 uriworkermap.properties 外的兩個檔案 都大概變動不大
uriworkermap.properties看名字跟內容就知,是用來設定哪些URL Pattern
是IIS要透過此connector交由tomcat處理的

isapi_redirect-1.2.27.properties
# Configuration file for the Jakarta ISAPI Redirector
# The path to the ISAPI Redirector Extension, relative to the website
# This must be in a virtual directory with execute privileges
extension_uri=/jakarta/isapi_redirect-1.2.27.dll

# Full path to the log file for the ISAPI Redirector
log_file=c:\TomcatConnector\isapi_redirect.log
# Log level (debug, info, warn, error or trace)
log_level=debug
# Full path to the workers.properties file
worker_file=c:\TomcatConnector\workers.properties
# Full path to the uriworkermap.properties file
worker_mount_file=c:\TomcatConnector\uriworkermap.properties

workers.properties
worker.list=wlb
worker.wlb.type=ajp13
worker.wlb.host=localhost
worker.wlb.port=8009

uriworkermap.properties
/examples/*=wlb

5. 設定IIS
a. 設定網頁服務延伸


b. 在站台上加入ISAPI filter

c. 在IIS站台上新增一虛擬目錄,命名為 jakarta 指向 Tomcat connector存放的位置
(本例為: c:\TomcatConnector),這個動作 對應到
isapi_redirect-1.2.27.properties 此設定檔內的下列設定:
extension_uri=/jakarta/isapi_redirect-1.2.27.dll

d. 注意,check download 下來的 isapi_redirect-1.2.27.dll 有無被 windows 封鎖


6. restart tomcat & iis

7. 連到 http://localhost:8080/examples 與 http://localhost/examples
check IIS 是否真的把符合 /exmaples/* 的 URL request 都餵給tomcat處理

8. 恭喜~ 大功告成

9. 後記: Tomcat網站上 說明有點遺漏
a. dll 可能被block的問題 官網上沒說明到
b. 除了 IIS 網頁服務延伸設定外,在 IIS 站台上 也要設定對應所使用的ISAPI位置
c. 官網上提供修改 windows registery的做法來記錄
workers.properties、uriworkermap.properties這些重要設定檔的位置
另外也提到可以在該 ISAPI dll 所在位置建立一isapi_redirect-1.2.27.properties
存放設定檔位置
當然~ 用第二種方法 感覺比較容易 :)


閱讀全文...