JAAS:Java Authentication and Authorization Service Java認(rèn)證和授權(quán)服務(wù),從jdk1.4開始就集成JAAS。
目前流行的Acegi中也提供了JAAS
JAAS的幾個(gè)核心類和接口:
1.Subject: 實(shí)際被認(rèn)證的人或者服務(wù)
2.Principal (interface): Subject的唯一標(biāo)識(shí)。一個(gè)Subject含有一個(gè)或多個(gè)Pricipal,比如一個(gè)人有身份證、護(hù)照等Pricipal
3.LoginContext
4.LoginModule (interface)
5.CallbackHandler (interface)
還有兩個(gè)配置文件:×××.conf(或config) 和 ×××..policy
JAAS首先使用一個(gè)LoginContext類來查找配置文件中的內(nèi)容,這些內(nèi)容可以用來對(duì)LoginModules進(jìn)行初始化。所有
LoginContext沒有指定的初始化參數(shù)都會(huì)包含在配置文件中。LoginContext向LoginModule傳遞一個(gè)CallbackHandler對(duì)象和一個(gè)Subject,如果LoginModule還需要其他認(rèn)證信息,它就會(huì)用CallbackHandler回調(diào)適當(dāng)?shù)膽?yīng)用程序,從而獲得這些信息。
在應(yīng)用程序中,一般這樣使用LoginContext:
try {
LoginContext loginContext = new LoginContext("Sample", callbackHandler ); //"Sample"定義在相關(guān)的conf文件中; callbackHandler見下面
loginContext.login(); //如果認(rèn)證失敗,則拋出異常
} catch (LoginException e) {
//do sth.
}
我們要使用JAAS,就需要實(shí)現(xiàn)上述接口,以及配置好文件
上面的代碼,只是在應(yīng)用時(shí),這樣寫就夠了。當(dāng)然,在這之前,還需要設(shè)置callbackHandler:
SampleCallbackHandler callbackHandler = new SampleCallbackHandler();
// 設(shè)置用戶名、密碼等需要驗(yàn)證的信息到callbackHandler里。具體怎么設(shè),看自己的SampleCallbackHandler怎么設(shè)計(jì)了
......
舉例:
public class SampleCallbackHandler implements CallbackHandler {
protected String username;
protected String password;
public void handle(Callback[] callbacks)
throws UnsupportedCallbackException { //這個(gè)方法是必須實(shí)現(xiàn)的,用來設(shè)置username和password到對(duì)應(yīng)的Callback變量中
for (int index = 0; index < callbacks.length; index++) {
if (callbacks[index] instanceof NameCallback) {
NameCallback ncb = (NameCallback) callbacks[index];
ncb.setName(username);
} else if (callbacks[index] instanceof PasswordCallback) {
PasswordCallback pcb = (PasswordCallback) callbacks[index];
pcb.setPassword(password.toCharArray());
} else if() { //如果還有其他需要驗(yàn)證的信息
...
}
}
//其他方法,諸如設(shè)置username和password
}
然后來說前面的"Sample"。這里的"Sample"對(duì)應(yīng)一個(gè)Sample.conf文件,這個(gè)文件的具體位置可以自己設(shè)置。conf文件中配置了對(duì)應(yīng)的LoginModule類,可以是一個(gè)或多個(gè),用來做不同的驗(yàn)證。
public class SampleLoginModule implements LoginModule {
....
}
LoginModule有5個(gè)方法需要實(shí)現(xiàn),簡單點(diǎn)寫個(gè)方法名得了:
public void initialize(Subject subject, CallbackHandler callbackHandler, Map arg2, Map arg3);
public boolean login() throws LoginException;
public boolean commit() throws LoginException;
public boolean abort() throws LoginException;
public boolean logout() throws LoginException;
業(yè)務(wù)邏輯主要在login()中實(shí)現(xiàn),步驟包括了從callbackHandler中讀取用戶名密碼,然后該從數(shù)據(jù)庫驗(yàn)證就從數(shù)據(jù)庫驗(yàn)證,該從配置文件驗(yàn)證就從配置文件驗(yàn)證,該從其他系統(tǒng)中驗(yàn)證就從其他系統(tǒng)中驗(yàn)證...
Pricipal的實(shí)現(xiàn)就不寫了,下面鏈接中的例子寫得很詳細(xì)。我的只是給自己理一個(gè)大概步驟,以后回顧起來也方便
不過Subject和Pricipal應(yīng)該有更重要的用處,比如在Authorization中,把pricipal和要可以執(zhí)行的相關(guān)操作對(duì)應(yīng)起來。這個(gè)還沒看下去,接觸的代碼中也沒用到。放到以后補(bǔ)充
更多內(nèi)容,可直接查看sun的JDK文檔http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html
實(shí)例:http://www.aygfsteel.com/fastunit/archive/2008/01/28/178204.html