14.2. カスタムモジュール


EAP セキュリティーフレームワークにバンドルされたログインモジュールがセキュリティー環境で機能しない場合は、独自のカスタムログインモジュール実装を作成できます。AuthenticationManager では、Subject プリンシパルの特定の使用パターンが必要です。AuthenticationManager で動作するログインモジュールを作成するには、JAAS Subject クラスの情報ストレージ機能と、これらの機能の予想される使用方法を理解している。
ここではこの要件を調べ、カスタムログインモジュールの実装に役立つ 2 つの抽象ベース LoginModule 実装を紹介します。
以下の方法を使用して、Subject に関連するセキュリティー情報を取得できます。
java.util.Set getPrincipals()
java.util.Set getPrincipals(java.lang.Class c)
java.util.Set getPrivateCredentials()
java.util.Set getPrivateCredentials(java.lang.Class c)
java.util.Set getPublicCredentials()
java.util.Set getPublicCredentials(java.lang.Class c)
Subject identity および roles の場合、EAP は最も論理的に選択されています。これは、getPrincipals()および getPrincipals (java.lang.Class) で取得したプリンシパルセットです。使用パターンは以下のとおりです。
  • ユーザー ID(ユーザー名、ソーシャルセキュリティー番号、従業員 ID など)は、サブジェクトプリンシパル セットに java.security.Principal オブジェクトとして保存されます。ユーザー ID を表す Principal 実装は、プリンシパルの名前に対するベース比較と等価でなければなりません。org.jboss.security.SimplePrincipal クラスとして適切な実装を利用できます。他の プリンシパル インスタンスは、必要に応じて設定された SubjectPrincipals に追加できます。
  • 割り当てられたユーザーロールは Principals セットに保存され、java.security.acl.Group インスタンスを使用して名前付きのロールセットにグループ化されます。Group インターフェースは Principals または Groupのコレクションを定義し、java.security.Principal のサブインターフェースです。
  • サブジェクト には任意の数のロールセットを割り当てることができます。
  • EAP セキュリティーフレームワークは、RolesCallerPrincipal という名前の 2 つのよく知られたロールセットを使用します。
    • Roles グループは、Subject が認証されたアプリケーションドメインで既知の名前付きロールの Principalのコレクションです。このロールセットは、ejb. isCallerInRole(String)などのメソッドによって使用されます。 EJB は、現在の呼び出し元が名前付きのアプリケーションドメインロールに属するかどうかを確認するために使用できます。メソッドパーミッションチェックを実行するセキュリティーインターセプターロジックは、このロールセットも使用します。
    • CallerPrincipal グループ は、アプリケーションドメインのユーザーに割り当てられる単一の Principal アイデンティティーで構成されます。gitops .getCallerPrincipal() メソッドは CallerPrincipal を使用して、アプリケーションドメインのオペレーション環境アイデンティティーからアプリケーションに適したユーザー ID へのマッピングを許可します。SubjectCallerPrincipal Group がない場合、アプリケーションのアイデンティティーは動作する環境アイデンティティーと同じです。

14.2.1. Subject Usage パターンのサポート

「カスタムモジュール」 で説明されている Subject Usage パターンの正しい実装を簡素化するために、EAP には、認証された Subject に正しいサブジェクトの使用を強制するテンプレートパターンを設定するログインモジュールが含まれます。

AbstractServerLoginModule

この 2 つの最も一般的なものは org.jboss.security.auth.spi.AbstractServerLoginModule クラスです。

javax.security.auth.spi.LoginModule インターフェースの実装を提供し、オペレーション環境セキュリティーインフラストラクチャーに固有のキータスクに抽象メソッドを提供します。クラスの主要な詳細は、例14.20「AbstractServerLoginModule Class Fragment」 で強調表示されています。JavaDoc コメントでは、サブクラスの責任が詳細に説明されています。
重要
loginOk インスタンス変数はピボットです。これは、ログインに成功する場合は true に設定する必要があります。または、ログインメソッドを上書きするすべてのサブクラスで false に設定する必要があります。この変数が正しく設定されている場合、コミットメソッドはサブジェクトを正しく更新しません。
フェーズでログを追跡すると、ログインモジュールを制御フラグと共にチェーンできます。これらの制御フラグは、認証プロセスの一環としてログインモジュールを正常に実行する必要はありません。

例14.20 AbstractServerLoginModule Class Fragment

package org.jboss.security.auth.spi;
/**
 *  This class implements the common functionality required for a JAAS
 *  server-side LoginModule and implements the PicketBox standard
 *  Subject usage pattern of storing identities and roles. Subclass
 *  this module to create your own custom LoginModule and override the
 *  login(), getRoleSets(), and getIdentity() methods.
 */
public abstract class AbstractServerLoginModule
    implements javax.security.auth.spi.LoginModule
{
    protected Subject subject;
    protected CallbackHandler callbackHandler;
    protected Map sharedState;
    protected Map options;
    protected Logger log;

    /** Flag indicating if the shared credential should be used */
    protected boolean useFirstPass;
    /** 
     * Flag indicating if the login phase succeeded. Subclasses that
     * override the login method must set this to true on successful
     * completion of login
     */
    protected boolean loginOk;
                
    // ...
    /**
     * Initialize the login module. This stores the subject,
     * callbackHandler and sharedState and options for the login
     * session. Subclasses should override if they need to process
     * their own options. A call to super.initialize(...)  must be
     * made in the case of an override.
     *
     * <p>
     * The options are checked for the  <em>password-stacking</em> parameter.
     * If this is set to "useFirstPass", the login identity will be taken from the
     * <code>javax.security.auth.login.name</code> value of the sharedState map,
     * and the proof of identity from the
     * <code>javax.security.auth.login.password</code> value of the sharedState map.
     *
     * @param subject the Subject to update after a successful login.
     * @param callbackHandler the CallbackHandler that will be used to obtain the
     * the user identity and credentials.
     * @param sharedState a Map shared between all configured login module instances
     * @param options the parameters passed to the login module.
     */
    public void initialize(Subject subject,
                           CallbackHandler callbackHandler,
                           Map sharedState,
                           Map options)
    {
        // ...
    }
    

    /**
     *  Looks for javax.security.auth.login.name and
     *  javax.security.auth.login.password values in the sharedState
     *  map if the useFirstPass option was true and returns true if
     *  they exist. If they do not or are null this method returns
     *  false.  
     *  Note that subclasses that override the login method
     *  must set the loginOk var to true if the login succeeds in
     *  order for the commit phase to populate the Subject. This
     *  implementation sets loginOk to true if the login() method
     *  returns true, otherwise, it sets loginOk to false.
     */
    public boolean login() 
        throws LoginException
    {
        // ...
    }
    
    /**
     *  Overridden by subclasses to return the Principal that
     *  corresponds to the user primary identity.
     */
    abstract protected Principal getIdentity();
                
    /**
     *  Overridden by subclasses to return the Groups that correspond
     *  to the role sets assigned to the user. Subclasses should
     *  create at least a Group named "Roles" that contains the roles
     *  assigned to the user.  A second common group is
     *  "CallerPrincipal," which provides the application identity of
     *  the user rather than the security domain identity.
     * 
     *  @return Group[] containing the sets of roles
     */
    abstract protected Group[] getRoleSets() throws LoginException;
}

UsernamePasswordLoginModule

2 つ目の抽象ベースログインモジュールは、org.jboss.security.auth.spi.UsernamePasswordLoginModule です。

このログインモジュールは、文字列ベースのユーザー名をユーザー ID として、認証クレデンシャルとして char[] パスワードを強制することで、カスタムログインモジュール実装をさらに単純化します。また、匿名ユーザー(null ユーザー名およびパスワードによって指定される)とロールのないプリンシパルへのマッピングもサポートします。クラスの主要な詳細は、以下のクラスフラグメントで強調表示されています。JavaDoc コメントでは、サブクラスの責任が詳細に説明されています。

例14.21 UsernamePasswordLoginModule Class Fragment

package org.jboss.security.auth.spi;

/**
 *  An abstract subclass of AbstractServerLoginModule that imposes a
 *  an identity == String username, credentials == String password
 *  view on the login process. Subclasses override the
 *  getUsersPassword() and getUsersRoles() methods to return the
 *  expected password and roles for the user.
 */
public abstract class UsernamePasswordLoginModule
    extends AbstractServerLoginModule
{
    /** The login identity */
    private Principal identity;
    /** The proof of login identity */
    private char[] credential;
    /** The principal to use when a null username and password are seen */
    private Principal unauthenticatedIdentity;

    /**
     * The message digest algorithm used to hash passwords. If null then
     * plain passwords will be used. */
    private String hashAlgorithm = null;

    /**
     *  The name of the charset/encoding to use when converting the
     * password String to a byte array. Default is the platform's
     * default encoding.
     */
     private String hashCharset = null;

    /** The string encoding format to use. Defaults to base64. */
    private String hashEncoding = null;
                
    // ...
                
    /** 
     *  Override the superclass method to look for an
     *  unauthenticatedIdentity property. This method first invokes
     *  the super version.
     *
     *  @param options,
     *  @option unauthenticatedIdentity: the name of the principal to
     *  assign and authenticate when a null username and password are
     *  seen.
     */
    public void initialize(Subject subject,
                           CallbackHandler callbackHandler,
                           Map sharedState,
                           Map options)
    {
        super.initialize(subject, callbackHandler, sharedState,
                         options);
        // Check for unauthenticatedIdentity option.
        Object option = options.get("unauthenticatedIdentity");
        String name = (String) option;
        if (name != null) {
            unauthenticatedIdentity = new SimplePrincipal(name);
        }
    }
                
    // ...
                
    /**
     *  A hook that allows subclasses to change the validation of the
     *  input password against the expected password. This version
     *  checks that neither inputPassword or expectedPassword are null
     *  and that inputPassword.equals(expectedPassword) is true;
     *
     *  @return true if the inputPassword is valid, false otherwise.
     */
    protected boolean validatePassword(String inputPassword,
                                       String expectedPassword)
    {
        if (inputPassword == null || expectedPassword == null) {
            return false;
        }
        return inputPassword.equals(expectedPassword);
    }
    
    /**
     *  Get the expected password for the current username available
     * via the getUsername() method. This is called from within the
     * login() method after the CallbackHandler has returned the
     * username and candidate password.
     *
     * @return the valid password String
     */
    abstract protected String getUsersPassword()
        throws LoginException;
}

ログインモジュールのサブクラス

AbstractServerLoginModuleUsernamePasswordLoginModule へのサブクラスの選択は、ログインモジュールを書き込む認証技術で文字列ベースのユーザー名と認証情報を使用できるかどうかに基づいています。文字列ベースのセマンティックが有効な場合は、サブクラスの UsernamePasswordLoginModule、他のサブクラス AbstractServerLoginModule

サブクラスの手順

カスタムログインモジュールを実行する必要がある手順は、選択したベースログインモジュールクラスによって異なります。セキュリティーインフラストラクチャーと統合するカスタムログインモジュールを作成する場合は、EAP セキュリティーマネージャーが想定される形式でログインモジュールが認証された Principal 情報を提供できるように、AbstractServerLoginModule または UsernamePasswordLoginModule をサブクラス化して開始する必要があります。

AbstractServerLoginModule をサブクラス化する場合は、以下を上書きする必要があります。
  • void initialize(Subject, CallbackHandler, Map, Map): 解析するカスタムオプションがある場合は。
  • boolean login(): 認証アクティビティーを実行する。ログインに成功したら、loginOk インスタンス変数を true に設定してください。失敗した場合は false に設定します。
  • プリンシパル getIdentity(): log ()ステップで認証されたユーザーの Principal オブジェクトを返します。
  • group[] getRoleSets(): login()時に認証された Principal に割り当てられたロールが含まれる Roles という名前の グループ を 1 つ以上返します。2 つ目の 共通グループCallerPrincipal という名前で、セキュリティードメインアイデンティティーではなくユーザーのアプリケーションアイデンティティーを提供します。
UsernamePasswordLoginModule をサブクラス化する場合、以下を上書きする必要があります。
  • void initialize(Subject, CallbackHandler, Map, Map): 解析するカスタムオプションがある場合は。
  • group[] getRoleSets(): login()時に認証された Principal に割り当てられたロールが含まれる Roles という名前の グループ を 1 つ以上返します。2 つ目の 共通グループCallerPrincipal という名前で、セキュリティードメインアイデンティティーではなくユーザーのアプリケーションアイデンティティーを提供します。
  • string getUsersPassword(): getUsername ()メソッドで利用可能な現在のユーザー名の想定されるパスワードを返します。getUsersPassword() メソッドは、callbackhandler がユーザー名およびパスワードを返した後に login() 内で呼び出されます。
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

Red Hat ドキュメントについて

Legal Notice

Theme

© 2026 Red Hat
トップに戻る