程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> WebSphere >> 在WebSphere Application Server Community Edition中配置Kerberos驗證

在WebSphere Application Server Community Edition中配置Kerberos驗證

編輯:WebSphere

WebSphere® Application Server Community Edition 目前不支持 Kerberos 驗證。本文介紹如何利用 IBM® Java™ Platform 提供的 Kerberos,實現在 WebSphere Application Server Community Edition 中執行 Kerberos 驗證。

簡介

IBM WebSphere Application Server Community Edition V2.1.1.2 (以下簡稱為 Community Edition)是一個基於 Apache Geronimo 2.1.4 的免費 Java Platform, Enterprise Edition 5.0 (Java EE 5) 認證應用服務器。Community Edition 使用 Java Authentication and Authorization Service (JAAS) 登錄模塊在 Web 應用程序中進行用戶驗證,使用 Java Authorization Contract for Containers (JACC) 進 行授權。

Kerberos 是由麻省理工學院開發的驗證協議。Kerberos 協議允許在不安全的計算機網絡上通信的計算機節點以一種安全的方式互相驗證。 Kerberos 協議的最新版本為 Version 5。

Community Edition 並不提供 Kerberos 協議實現。在本文中,您將利用 IBM Java Platform 提供的 Kerberos 協議實現在 Community Edition 中驗證用戶並對用戶授權。為實現本文的目的,我們使用一個 Microsoft® Active Directory 服務器(以下簡稱為 Active Directory)作為一個用戶資源庫。本文需要 WebSphere Application Server Community Edition V2.1.1.2 或更高版本。

Kerberos: 它是如何工作的?

Kerberos 使用對稱密匙密碼系統,需要一個稱為 Key Distribution Center (KDC) 的可信第三方,KDC 包含一個 Authentication Server (AS) 和一個 Ticket Granting Server (TGS)。KDC 維護一個秘密密匙數據庫。網絡上的每個實體(用戶或服務)都 與 KDC 共享一個秘密密匙,這個秘密密匙只有 KDC 和實體自身知曉。這樣,通過這個秘密密匙就可以對實體進行身份驗證。Kerberos 使用票 據(ticket),稱為 “Kerberos 票據”,該票據擁有時間戳且存在時間很短。因此,實體必須保持時間同步。

實體使用一個共享秘密(通常是密碼)對 Authentication Server 進行驗證,並接收一個 Ticket Granting Ticket (TGT)。然後它聯系 Ticket Granting Server,使用 TGT 驗證其身份並請求一個服務。TGS 驗證該實體是否有權使用服務並發送一個 Service Ticket (ST)。該實 體然後聯系 Service Server (SS),使用 ST 證明自己有權利用服務,然後實際使用服務。實體能夠重復使用 TGT 獲取額外的 ST 以使用 SS ,無需再次使用 AS 驗證自己。Kerberos 協議經過特殊設計,無需在網絡上傳播共享秘密(如密碼)就可以進行驗證。使用 Kerberos 驗證時 ,用戶通常使用一個輸入設備(如鍵盤)輸入他們的憑證,而服務使用一個 Keytab 文件存儲用戶憑證,並使用它們對 KDC 進行驗證。

Kerberos 和 Community Edition

Community Edition 不 提供 Kerberos 協議的實現。IBM Java Platform 通過 com.ibm.security.auth.module.Krb5LoginModule 類提供 Kerberos 協議的一個實現。為了利用 Java Platform 提供的 Kerberos 實現,我們創建一個包裝 Krb5LoginModule 的 LoginModule 實現, 並將所有 LoginModule API 調用委托給 Krb5LoginModule。KerberosLoginModule 的代碼如清單 1 所示。

清單 1. KerberosLoginModule.java

package org.apache.geronimo.security.realm.providers;

import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class KerberosLoginModule implements LoginModule {

   private static Log log = LogFactory.getLog(KerberosLoginModule.class);
   private Subject subject;
   private LoginModule krb5LoginModule;
   private Subject krb5Subject;
   private Principal addOnPrincipal;

   public void initialize(Subject subject, CallbackHandler callbackHandler,
  Map sharedState, Map options) {
     this.subject = subject;
     String krb5LoginModuleClass = (String) options.get("krb5LoginModuleClass");
     try {
       krb5LoginModule = (LoginModule)Class.forName(krb5LoginModuleClass)
.newInstance();
     } catch (Exception e) {
       log.error("Initialization failed", e);
       throw new IllegalArgumentException("Unable to configure
kerberos login module: " + e.getMessage(),e);
     }

     Map options1 = new HashMap();
     for(Object key : options.keySet()) {
       String key1 = (String) key;
       if(key1.startsWith("krb_")) {
         options1.put(key1.substring(4), options.get(key1));
       }
     }

     krb5Subject = new Subject();
krb5LoginModule.initialize(krb5Subject, callbackHandler, sharedState,
options1);
String addOnPrincipalClass = (String) options.get("addOnPrincipalClass");
String addOnPrincipalName = (String) options.get("addOnPrincipalName");
if(addOnPrincipalClass != null && !addOnPrincipalClass.equals("")) {
   try {
   addOnPrincipal = (Principal) Class.forName(addOnPrincipalClass).getConstructor
   (String.class).newInstance(addOnPrincipalName);
       } catch (Exception e) {
        log.error("Initialization failed", e);
        throw new IllegalArgumentException("Unable to configure kerberos login
        module: " + e.getMessage(), e);
       }
     }
   }

   public boolean login() throws LoginException {
     return krb5LoginModule.login();
   }

   public boolean commit() throws LoginException {
     boolean result = krb5LoginModule.commit();
     if(result) {
      if(addOnPrincipal != null) subject.getPrincipals().add(addOnPrincipal);

subject.getPrincipals().addAll(krb5Subject.getPrincipals());
     subject.getPublicCredentials().addAll(krb5Subject.getPublicCredentials());
     subject.getPrivateCredentials().addAll(krb5Subject.getPrivateCredentials());
     }
     return result;
   }

public boolean abort() throws LoginException {
     return krb5LoginModule.abort();
   }

public boolean logout() throws LoginException {
   if(!subject.isReadOnly()) {
   // Remove principals and credentials added by this LoginModule
   if(addOnPrincipal != null) subject.getPrincipals().remove(addOnPrincipal);
subject.getPrincipals().removeAll(krb5Subject.getPrincipals());

   subject.getPublicCredentials().removeAll(krb5Subject.getPublicCredentials());
   subject.getPrivateCredentials().removeAll(krb5Subject.getPrivateCredentials());
     }
     return krb5LoginModule.logout();
   }
}

KerberosLoginModule 擁有以下 LoginModule 選項:

krb5LoginModuleClass:指定由 Java Platform 提供的 Kerberos 協議實現的完全限定名。這個類必須實現 javax.security.auth.spi.LoginModule 接口。由於我們將使用 IBM Java Platform 提供的 Krb5LoginModule,這個值為 com.ibm.security.auth.module.Krb5LoginModule。

addOnPrincipalClass:指定登錄成功後添加到主題(subject)的主體(principal)的類的完全限定名。除了使用 krb5LoginModuleClass 登錄導致的其他主體外,這個主體也將被添加到主題。如果不需要添加更多主體,則不要使用這個選項。

addOnPrincipalName:指定要添加到主題的主體的名稱。這個選項只在指定了 addOnPrincipalClass 的情況下使用。

krb_*:傳遞到 krb5LoginModuleClass 的 initialize() 方法的任意選項必須使用一個 “krb_” 前綴。在選項傳遞到 initialize() 方 法之前,前綴 “krb_” 將從選項名中刪除。例如 krb_debug=true 將以 debug=true 形式傳遞到 initialize() 方法。

KerberosLoginModule.initialize() 方法為使用 krb5LoginModuleClass 選項配置的類創建一個實例,它只使用名稱以前綴 “krb_” 開 頭的那些選項初始化該實例,但初始化時將刪除前綴。它還創建一個通過 addOnPrincipalClass 和 addOnPrincipalName 選項配置的附加 (add-on)主體。成功驗證後,KerberosLoginModule.commit() 方法將 krb5LoginModuleClass 登錄導致的所有 Principals、Public Credentials 和 Private Credentials 以及附加 Principal 添加到 Subject。KerberosLoginModule 類用於創建使用 Kerberos 協議在 Community Edition 中執行驗證的安全域。

在 Microsoft Active Directory 中建立用戶

安裝和配置 Microsoft Active Directory 服務器超出了本文的范圍。根據我們的配置,我們已經在端口 88 啟動了 Key Distribution Centre (KDC)。執行以下步驟以向 Active Directory 服務器添加新用戶。

啟動 Active Directory Users and Computers 並選擇 Users,如圖 1 所示。

圖 1. Active Directory 用戶和計算機

右鍵單擊 Users 並選擇 New > User,如圖 2 所示。

Figure 2. 創建新用戶

在對話框中,填充 First Name、Last Name 和 User logon name 並單擊 Next,如圖 3 所示。

圖 3. 創建新用戶 —— 用戶細節

輸入用戶密碼並單擊 Next,如圖 4 所示。

圖 4. 創建新用戶 —— 密碼

單擊 Finish 完成新用戶添加,如圖 5 所示。

圖 5. 創建新用戶 —— 新用戶已添加

可以看到,新創建的用戶在 “Users” 下列示。

建立客戶機

這個步驟要求將 Kerberos 配置文件復制到預定義的位置。對於 Windows 客戶機,這個文件名為 “krb5.ini”,位於 “C:/winnt/” 目 錄中。對於 Linux 客戶機,這個文件名為 “krb5.conf”,位於 “/etc” 目錄中。我們使用的 Kerberos 配置文件如清單 2 所示。

清單 2. Kerberos 配置文件 —— krb5.ini

[libdefaults]
default_realm = AUSTIN.IBM.COM
default_tkt_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc
default_tgs_enctypes = rc4-hmac,des-cbc-md5,des-cbc-crc

[realms]
AUSTIN.IBM.COM = {
   kdc = ad1ldap.austin.ibm.com:88
}

[domain_realm]
austin.ibm.com = AUSTIN.IBM.COM
.austin.ibm.com = AUSTIN.IBM.COM

下面讓我們看看這個配置文件中的每個部分和條目。

第一個部分是 [libdefaults],它描述 Kerberos V5 庫使用的默認值。這個部分中的其他字段介紹如下:

default_realm:這是將用於客戶機和主機之間的通信的默認域。如果您使用一個主體名 “ashish”,AUSTIN.IBM.COM 將默認附加到主體 名之後,這樣,最終的主體為 [email protected]

default_tgs_enctypes:這個字段指定 KDC 返回的會話密匙加密。當 Microsoft Active Directory 作為 KDC 使用時,確保在這個字段中 指定 rc4-hmac。

default_tkt_enctypes:這個字段指定客戶機將請求的會話密匙加密類型的列表。

第二個部分是 [realms],它描述域和 KDC 服務器映射的細節。在清單 2 中,AUSTIN.IBM.COM 已經被映射到 ad1ldap.austin.ibm.com:88 。這裡,ad1ldap.austin.ibm.com 是 hostName,88 是正在運行 KDC 服務器的端口號。

第三個部分是 [domain_realm],它描述從子域和域名到 Kerberos 域名的映射細節。如果一個主機具有完全限定域名,則這個部分能夠確 定該主機所處的域。

將自定義 Kerberos 登錄模塊 JAR 添加到資源庫

Community Edition 的當前版本不包含 KerberosLoginModule 實現。本文提供一個包含 KerberosLoginModule 類(如清單 1 所示)的 自 定義登錄模塊 JAR,以幫助您在 Community Edition 中創建一個 Kerberos 安全域。這個 JAR 需要添加到 Community Edition 資源庫。執行 以下步驟將這個登錄模塊 JAR 添加到 Community Edition 資源庫:

啟動 Community Edition,在您的浏覽器中打開 http://localhost:8080/console/。

輸入用戶名 system 和密碼 manager。單擊 Login,這將在管理控制台中打開 Welcome 頁面,如圖 6 所示。

圖 6. 管理控制台 —— Welcome 頁面

單擊 Console Navigation 下的 Repository 啟動 Repository portlet(如圖 7 所示)。

圖 7. Repository portlet

浏覽到自定義登錄模塊 JAR 的下載位置。如圖 7 所示,命名字段並單擊 Install。這將把登錄模塊 JAR 安裝到 Community Edition 資源 庫中。

創建一個 Kerberos 域

本小節將介紹使用 Community Edition Administrative Console 創建一個 Kerberos 域的步驟:

在 Security 下的 Console Navigation 中單擊 Security Realms 鏈接,如圖 8 所示。

圖 8. 啟動 Security Realms portlet

在 Security Realms portlet 中, 單擊 Add new security realm,如圖 9 所示。

圖 9. 啟動新安全域的頁面

在下一個頁面中,將域名設置為 kerberos-realm,選擇 Other 作為域類型,然後單擊 Next,如圖 10 所示。

圖 10. 創建新的安全域

如圖 11 所示填充表單。從下拉列表框中選擇登錄模塊 JAR,這是此前添加到資源庫中的那個 JAR。將 Login Module Class 命名為 org.apache.geronimo.security.realm.providers.KerberosLoginModule。添加如清單 3 所示的配置選項。

清單 3. 創建安全域時的配置選項

addOnPrincipalName=admin
addOnPrincipalClass=org.apache.geronimo.security.realm.providers.
GeronimoGroupPrincipal
krb_debug=true
krb5LoginModuleClass= com.ibm.security.auth.module.Krb5LoginModule

圖 11. 創建新的安全域 —— 配置

完成後,浏覽到頁面底部。單擊 Show Plan 顯示 Kerberos 域計劃,如圖 12 所示。

圖 12. 顯示創建的安全域計劃

在下一個屏幕上,您將看到已創建的計劃顯示在一個文本框中,如圖 13 所示。您也可以復制該計劃以備將來參考。單擊 Deploy 將安全域 部署到 Community Edition。

圖 13. 部署安全域計劃

如果部署成功,您將看到 “kerberos-realm” 列示在 Security Realms 頁面中,如圖 14 所示。

圖 14. 成功部署 Kerberos 域

部署並測試樣例應用程序

為測試 Kerberos 域,本文提供了一個 樣例應用程序。執行以下步驟部署並測試這個樣例應用程序:

在 Applications 下的 Console Navigation 中單擊 Deploy New,如圖 15 所示。

圖 15. 啟動 deploy new portlet

浏覽到下載樣例應用程序的位置,選擇 SimpleWebApp-Subject.war 作為 Archive,選擇 SimpleWebApp-Subject-plan.xml 作為 Plan,如 圖 16 所示。

圖 16. 安裝應用程序

單擊 Install 部署樣例應用程序。

完成後,啟動 URL http://localhost:8080/kerberos-realm-demo/admin/admin.jsp。這將顯示一個屏幕以提供登錄憑證(如圖 17 所示) 。

圖 17. 簡單 Web 應用程序 —— 登錄屏幕

輸入此前創建的 Microsoft Active Directory 用戶名和密碼並單擊 Login。

成功驗證後,您將看到一個歡迎頁面,該頁面表明主體 [email protected] 已添加到 admin 組。該頁面還列示了生成的 Kerberos 票據,如圖 18 所示。

圖 18. 成功驗證後的歡迎頁面和其他工件

注意,除了 KerberosPrincipal 外,Subject 還使用 addOnPrincipal 選項在域中配置了 GeronimoGroupPrincipal。

現在嘗試使用一個錯誤密碼進行登錄,您將看到一條登錄失敗消息,如圖 19 所示。

圖 19. 登錄失敗果

結束語

本文展示了如何通過創建一個 KerberosLoginModule 包裝器在 Community Edition 中驗證用戶,以利用 IBM Java Platform 提供的 Kerberos 協議實現。本文還通過一個樣例應用程序展示如何使用 Kerberos 驗證列示在 Microsoft Active Directory 服務器中的用戶。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved