PrivilegedAction 任何實現PrivilegedAction介面的類都封裝了一些代碼,Java客戶端可以在由已填充的Subject定義的安全上下文中運行這些代碼.在這種安全上下文下調用已授權動作之前,weblogic.security.Security.runAs( )方法允許客戶端把一個Subject與當前線程相關聯. 示例JAAS客戶端 讓我們考察一下如何構建一個能夠為WebLogic對自身進行身份驗證的JAAS客戶端.我們將使用從上至下的方法講述這個例子,從JAAS客戶端需要實現的內容開始,然後再細分為其實現的單個組件.讓我們從主類SimpleJAASClient開始,採取以下步驟: 它從命令行讀取用戶名、密碼和URL作為輸入參數. 它嘗試連接到特定的URL,然後使用所提供的用戶名和密碼對客戶端進行身份驗證. 它在新獲得的已驗證對象下執行一個已授權的動作.例17-1列出了我們的JAAS客戶端的源代碼. 例17-1列出了我們的JAAS客戶端的源代碼. 例17-1.示例JAAS客戶端 package com.oreilly.wlguide.security.jaas; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; public class SimpleJAASClient { public static void main(String[] args) { String username = args[0]; String password = args[1]; String url = args[2]; LoginContext loginContext = null; // Create a LoginContext using our own CallBackHander try { loginContext = new LoginContext("Simple", new SimpleCallbackHandler(username, password, url)); } catch (Exception e) { // Can get a SecurityException or a LoginException e.printStackTrace( ); System.exit(-1); } // Now authenticate. If we don't get an exception, we succeeded try { loginContext.login( ); } catch (Exception e) { // Can get FailedLoginException, AccountExpiredException, // or CredentialExpiredException e.printStackTrace( ); System.exit(-1); } // Retrieve authenticated subject and perform action using it Subject subject = loginContext.getSubject( ); SimpleAction simpleAction = new SimpleAction(url); weblogic.security.Security.runAs(subject, simpleAction); } } 注意我們是如何突出JAAS客戶端的重點部分的.我們的第一個關鍵步驟是建立LoginContext對象: loginContext = new LoginContext("Simple",new SimpleCallbackHandler(username, password, url)); LoginContext對象使用將在JAAS身份驗證期間使用的CallBackHandler和LoginModule實例初始化了客戶端.構造器帶的第二個參數是我們自己的CallBackHandler實例,LoginModule將使用它來獲得用戶證書,以及將對我們的客戶端進行身份驗證的WebLogic實例的URL. 構造器帶的第一個參數是Simple,用於為客戶端查找適當的LoginModule.JAAS客戶端依賴於一個配置文件,該配置文件把JAAS登錄模塊的名稱映射為它們的實現,而且還指定了另外的參數.例17-2列出了我們使用的JAAS配置文件. 例17-2. 登錄配置文件jaas.config Simple { weblogic.security.auth.login.UsernamePasswordLoginModule required }; 我們的配置文件包含一個Simple入口,在給定用戶名和密碼的基礎上為身份驗證指定了WebLogic的LoginModule: weblogic.security.auth.login.UsernamePasswordLoginModule.當運行JAAS客戶端時,必須使用一個系統屬性指定該配置文件的位置.下面說明了如何運行我們的示例JAAS客戶端: java -Djava.security.auth.login.config=jaas.config com.oreilly.wlguide.security.jaas.SimpleJAASClient system pssst t3://10.0.10.10: 8001/ 這樣,我們就可以配置LoginContext以使用WebLogic的 LoginModule,它支持使用用戶名-密碼組合的身份驗證.稍後,我們將看一看如何使用JAAS配置文件透明地使用LoginModule實現來代替這種方法. 建立登錄上下文之後,我們調用了loginContext.login( )方法來執行實際的登錄.我們的LoginContext將利用已配置的登錄模塊和回調處理對象,並嘗試藉助伺服器對客戶端進行身份驗證.如果客戶端成功通過身份驗證,可以從LoginContext獲得已驗證的主題: Subject subject = loginContext.getSubject( ); 這個已驗證Subject上的getPrincipals( )方法將獲得與用戶相關的所有主體.例如,如果我們的JAAS客戶端使用系統管理員的證書進行身份驗證,已驗證的Subject將具有兩個主體:代表用戶的system,和代表用戶的組的Administrators.現在,我們可以使用這個主題來執行一個或多個「已授權」的操作.換句話說,這些操作是在這個已驗證主題的上下文中執行的: weblogic.security.Security.runAs(subject, simpleAction); 這裡給出一個忠告——客戶端必須調用WebLogic的Security類上的runAs( )方法.runAs( )方法帶有兩個參數:已驗證的Subject和一個PrivilegedAction對象,後者包裝了應用程序與伺服器的特定交互.例17-3說明了我們的JAAS客戶端希望執行的操作. 例17-3. 一個非常簡單的操作 package com.oreilly.wlguide.security.jaas; import java.security.PrivilegedAction; import java.sql.Connection; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; public class SimpleAction implements PrivilegedAction { private static final String JNDI_NAME = "jdbc.xpetstore"; private String url; public SimpleAction(String url) { this.url = url; } public Object run( ) { Object obj = null; try { Context ctx = null; Hashtable ht = new Hashtable( ); ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); ht.put(Context.PROVIDER_URL, url); // Get a context for the JNDI lookup ctx = new InitialContext(ht); // do any work here DataSource ds =(javax.sql.DataSource) ctx.lookup(JNDI_NAME); // ... } catch (Exception e) { e.printStackTrace( ); } return obj; } } 在這裡,需要考慮以下重點: 類實現 java.security.PrivilegedAction介面.然後,任何JAAS 客戶端都可以在已驗證Subject的上下文中調用這個類的一個實例. run( )方法封裝了客戶端與伺服器的交互.通常,客戶端將建立一個JNDI上下文,使用它來獲取綁定到JNDI樹的資源,然後調用/訪問這些資源.在前面的例子中,我們使用了JNDI上下文來獲得JDBC數據源. 當我們在PrivilegedAction.run( )方法中建立JNDI上下文時,我們沒有為JNDI身份驗證提供任何用戶證書.JAAS客戶端提供已驗證的Subject給runAs( )方法,確保PrivilegedAction對象是在這個主題的上下文中調用的.也就是說,runAs( )方法負責把已驗證的主題與當前線程關聯起來. 例17-4列出了我們的CallBackHandler類的源代碼.通常,回調處理程序將與客戶端交互,提示用戶輸入用於身份驗證的用戶名和密碼.在我們的簡單JAAS客戶端的例子中,我們提供了必需的證書和URL給我們的回調處理程序的構造器,這樣回調便可容易地返回這些信息. 例17-4. 一個簡單的回調處理器 package com.oreilly.wlguide.security.jaas; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import weblogic.security.auth.callback.URLCallback; public class SimpleCallbackHandler implements CallbackHandler { private String username = null; private String password = null; private String url = null; public SimpleCallbackHandler(String pUsername, String pPassword, String pUrl) { username = pUsername; password = pPassword; url = pUrl; } public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i ) { if (callbacks[i] instanceof NameCallback) { NameCallback nc = (NameCallback) callbacks[i]; nc.setName(username); } else if (callbacks[i] instanceof URLCallback) { URLCallback uc = (URLCallback) callbacks[i]; uc.setURL(url); } else if (callbacks[i] instanceof PasswordCallback) { PasswordCallback pc = (Pa
[火星人
]
安全技術 Java與安全性,第2部分二 已經有404 次圍觀
本文地址: http://coctec.com/docs/java/show-post-61988.html