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

如何自動回收 IIS 的 Application Pool


在IIS6 中,ASP.NET default 是跑在 worker process isolation mode

即,我們可以透過 Application Pool 的設定,讓不同的 ASP.NET 應用程式,跑在不同的 application pool中,由不同的 worker process 來處理,這樣的做法,可以避免將一個雞蛋放在同一個籠子裡,讓表現異常的應用程式,沒法影響到在其它Application Pool 中的程式

談到「異常」的應用程式...

有些人寫出來的APP就是莫明奇妙會掛點、Hang住、出問題~
積極的處理方式是做完整的測試、Code Review將問題查出並修正
消極的處理方式則是進行 IIS重啟(iisreset) 或 Application Pool Recycle(應用程式集區回收),看看有沒有辦法恢復正常

因使用IIS重啟是整個IIS都會被影響到,所以 可以就發生問題的Application Pool 進行回收 以降低影響範圍

Application Pool Recycle 這種被動的方式,除了可透過application pool 設定進行定期的回收外:


有時,我們可能想要透過一監測程式,在監測到有異常時,才執行application pool 回收
更甚者,我們可能在一台主機監測,而需要回收遠端主機的 application pool...

此時,主要可透過兩種方式來達成:

A. 透過 WMI 的方式, 我有 google 到下列的方式,但未試做:
http://gallery.technet.microsoft.com/ScriptCenter/en-us/22b10d93-e734-4fda-8ebe-2df30e54c64b
http://www.vistax64.com/powershell/103705-remote-application-pool-recycle-using-wmi-powershell.html
http://forums.iis.net/p/1033115/1421721.aspx

B. 透過 IIS 主機內建的 c:\windows\system32\iisapp.vbs 此 script,並搭配如 psexec 此類的遠端執行shell 指命的tool, 來達成:

iisapp.vbs 用法:

C:\>cscript c:\windows\system32\iisapp.vbs /a {ApplicationPoolName} /r

搭配 psexec 在 C# 程式中,可以用這種方式來達成遠端回收 application pool的效果:

Process process = new Process();
process.StartInfo.FileName = @"D:\PsTools\psexec.exe";
process.StartInfo.Arguments = @"\\{原端主機IP} -u {帳號} -p {密碼} cscript c:\windows\system32\iisapp.vbs /a {要回收的application pool name} /r";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.WaitForExit();

psexec 為 PsTools 內的一項utility,可在此下載


閱讀全文...

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. 這是我測試的結果啦~ 若大家有其它經驗 請再跟我分享 :)


閱讀全文...