開發 Liberty 的自訂 JASPIC 鑑別提供者

您可以建立類別來實作 JSR 196: Java™ Authentication Service Provider Interface for Containers 規格中說明的必要介面,以開發自訂 Java Authentication SPI for Containers (JASPIC) 鑑別提供者。

開始之前

請檢閱 JSR 196: Java Authentication Service Provider Interface for Containers 規格中有關 JASPIC 鑑別提供者和模組的特定介面實作需求。

關於這項作業

只要協力廠商鑑別提供者符合 Java Authentication SPI for Containers (JASPIC) 1.1 版指定的 Servlet 儲存器,WebSphere® Application Server Liberty 就支援使用該協力廠商鑑別提供者。

Servlet 儲存器定義了一些介面,安全執行時期環境會使用這些介面,並與 WebSphere Application Server 中的 Web 儲存器搭配使用,以便在應用程式處理 Web 要求之前和之後,呼叫鑑別模組。必須在安全配置中啟用 JASPIC,才會執行使用 JASPIC 模組的鑑別。

如果要開發自訂鑑別提供者,請建立類別來實作 JSR 196: Java Authentication Service Provider Interface for Containers 規格中說明的必要介面。提供者可以使用一個或多個鑑別模組來進行鑑別。模組可以使用回呼來執行鑑別,也可以將必要的使用者身分資訊手動新增至用戶端主體。

程序

  1. 建立一個實作 javax.security.auth.message.config.AuthConfigProvider 介面的類別。
    AuthConfigProvider 實作類別必須定義一個具有兩個引數的公用建構子,以及 getServerAuthConfig 公用方法:
    import java.util.Map;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.config.AuthConfigFactory;
    import javax.security.auth.message.config.AuthConfigProvider;
    import javax.security.auth.message.config.ServerAuthConfig;
    
    public class SampleAuthConfigProvider implements AuthConfigProvider {
    
            public SampleAuthConfigProvider(Map<String, String> properties, AuthConfigFactory factory) {
                    ...
            }
            public ServerAuthConfig getServerAuthConfig(String layer, String appContext, CallbackHandler handler)
                    throws AuthException {
                    ...
            }
    }

    當應用程式 Web 模組要處理的要求送達時,WebSphere Application Server 會使用 AuthConfigProvider 實作類別的實例。會使用 getServerAuthConfig 方法,來取得 ServerAuthConfig 實例。authentication 模組會使用方法呼叫中的 CallbackHandler 引數。

  2. 建立一個實作 javax.security.auth.message.config.ServerAuthConfig 介面的類別。
    ServerAuthConfig 實作類別必須定義 getAuthContextIDgetAuthContext 公用方法:
    import java.util.Map;
    import javax.security.auth.Subject;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.MessageInfo;
    import javax.security.auth.message.config.ServerAuthConfig;
    import javax.security.auth.message.config.ServerAuthContext;
    
    public class SampleServerAuthConfig implements ServerAuthConfig {
    
            public String getAuthContextID(MessageInfo messageInfo) throws IllegalArgumentException {
                    ...
            }
            public ServerAuthContext getAuthContext(String authContextID, Subject serviceSubject, Map properties) 
                    throws AuthException {
                    ...
            }
    }

    會使用 ServerAuthConfig 實作類別中的 getAuthContextIDgetAuthContext 方法,來取得 ServerAuthContext 實例。

  3. 建立一個實作 javax.security.auth.message.config.ServerAuthContext 介面的類別。
    ServerAuthContext 實作類別必須定義 validateRequestsecureResponse 公用方法:
    import javax.security.auth.Subject;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.AuthStatus;
    import javax.security.auth.message.MessageInfo;
    import javax.security.auth.message.config.ServerAuthContext;
    
    public class SampleServerAuthContext implements ServerAuthContext {
    
            public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) 
                    throws AuthException {
                    ...
            }
            public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) 
                    throws AuthException {
                    ...
            }
    }

    會使用 ServerAuthContext 實作類別中的 validateRequest 方法來呼叫模組,以便鑑別所接收的 Web 要求訊息。如果鑑別結果成功,Web 儲存器會分派所接收的 Web 要求訊息,而由目標 Web 模組在應用程式中處理該 Web 要求訊息。如果鑑別結果失敗,則會拒絕該要求,並提供適當的回應狀態。

  4. 建立一個實作 javax.security.auth.message.module.ServerAuthModule 介面的類別。
    ServerAuthModule 實作類別必須定義 initializevalidateRequestsecureResponse 公用方法:
    import javax.security.auth.Subject;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.AuthStatus;
    import javax.security.auth.message.MessageInfo;
    import javax.security.auth.message.MessagePolicy;
    import javax.security.auth.message.module.ServerAuthModule;
    
    public class SampleAuthModule implements ServerAuthModule {
    
            public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, Map options) 
                    throws AuthException {
                    ...
            }
    
            public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
                    throws AuthException {
                    ...
            }
    
            public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) 
                    throws AuthException {
                    ...
            }
            public void cleanSubject(MessageInfo messageInfo, Subject subject) 
                    throws AuthException {
                    ...
            }
    }

    ServerAuthContext 實作類別會呼叫 ServerAuthModule 實作類別中的 initialize 方法,來起始設定 authentication 模組,並使其與 ServerAuthContext 實例相關聯。

    會使用此類別中的 validateRequestsecureResponse 方法,來鑑別所接收之 javax.security.auth.message.MessageInfo 中包含的 javax.Servlet.http.HttpServletRequestjavax.Servlet.http.HttpServletResponse。這些方法可以使用 initialize 方法中所收到的 CallbackHandler 實例,來與 WebSphere 安全執行時期互動,以驗證使用者密碼,以及與作用中的使用者登錄互動,以擷取使用者的唯一 ID 和群組成員資格。所擷取的資料會放在用戶端主體中之專用認證集的雜湊表中。WebSphere Application Server 在實作 CallbackHandler 時,支援下列三項回呼:
    • CallerPrincipalCallback
    • GroupPrincipalCallback
    • PasswordValidationCallback

    WebSphere Application Server 預期使用 PasswordValidationCallback.getUsername()CallerPrincipalCallback.getName() 取得的名稱值相同。如果不相同,會產生無法預期的結果。CallbackHandler 程序的 handle() 方法會循序處理方法的引數陣列中所提供的每一項回呼。因此,用戶端主體專用認證中的名稱值集,就是從所處理的最後一項回呼取得的。

    如果鑑別模組不使用 CallbackHandler,且 validateRequest 傳回成功狀態,WebSphere Application Server 會要求 clientSubject 中必須包含 Hashtable 實例及使用者身分資訊,以便可以執行自訂登入,來取得使用者的認證。此 Hashtable 可以新增至用戶端主體,如下列範例所示:
    import java.util.Hashtable;
    import java.util.String;
    import javax.security.auth.Subject;
    import javax.security.auth.message.AuthException;
    import javax.security.auth.message.AuthStatus;
    import javax.security.auth.message.MessageInfo;
    import com.ibm.wsspi.security.registry.RegistryHelper;
    import com.ibm.wsspi.security.token.AttributeNameConstants.AttributeNameConstants;
    
    public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
           throws AuthException {
           ...
           UserRegistry reg = RegistryHelper.getUserRegistry(null);
           String uniqueid = reg.getUniqueUserID(username);
    
           Hashtable hashtable = new Hashtable();
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uniqueid);
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username);
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_PASSWORD, password);
           hashtable.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groupList); //optional
           clientSubject.getPrivateCredentials().add(hashtable);
           ...
    }

    如需 Hashtable 需求及自訂登入的相關資訊,請參閱開發用於系統登入配置的 JAAS 自訂登入模組


指示主題類型的圖示 作業主題

檔名:twlp_develop_jaspic.html