16.2.2. カスタム LoginModule の例
以下の情報は、
UsernamePasswordLoginModule を拡張し、JNDI ルックアップからユーザーのパスワードとロール名を取得するカスタムログインモジュールの例を作成するのに役立ちます。
本項の最後では、
password/<username> 形式 (<username> は認証中の現ユーザー) の名前を使用してコンテキストでルックアップを実行するとユーザーのパスワードが返されるカスタムの JNDI コンテキストログインモジュールが作成されます。同様に、roles/<username> 形式のルックアップは要求されたユーザーのロールを返します。JndiUserAndPassLoginModule カスタムログインモジュールのソースコードは 例16.22「JndiUserAndPassLoginModule カスタムログインモジュール」 を参照してください。
これにより JBoss の
UsernamePasswordLoginModule が拡張されるため、JndiUserAndPassLoginModule はユーザーのパスワードとロールを JNDI ストアから取得することに注意してください。JndiUserAndPassLoginModule は JAAS LoginModule 操作とやりとりしません。
例16.22 JndiUserAndPassLoginModule カスタムログインモジュール
package org.jboss.book.security.ex2;
import java.security.acl.Group;
import java.util.Map;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import org.jboss.logging.Logger;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
/**
* An example custom login module that obtains passwords and roles for a user from a JNDI lookup.
*
* @author Scott.Stark@jboss.org
*/
public class JndiUserAndPassLoginModule extends UsernamePasswordLoginModule {
/** The JNDI name to the context that handles the password/username lookup */
private String userPathPrefix;
/** The JNDI name to the context that handles the roles/username lookup */
private String rolesPathPrefix;
private static Logger log = Logger.getLogger(JndiUserAndPassLoginModule.class);
/**
* Override to obtain the userPathPrefix and rolesPathPrefix options.
*/
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
super.initialize(subject, callbackHandler, sharedState, options);
userPathPrefix = (String) options.get("userPathPrefix");
rolesPathPrefix = (String) options.get("rolesPathPrefix");
}
/**
* Get the roles the current user belongs to by querying the rolesPathPrefix + '/' + super.getUsername() JNDI location.
*/
@Override
protected Group[] getRoleSets() throws LoginException {
try {
InitialContext ctx = new InitialContext();
String rolesPath = rolesPathPrefix + '/' + super.getUsername();
String[] roles = (String[]) ctx.lookup(rolesPath);
Group[] groups = { new SimpleGroup("Roles") };
log.info("Getting roles for user=" + super.getUsername());
for (int r = 0; r < roles.length; r++) {
SimplePrincipal role = new SimplePrincipal(roles[r]);
log.info("Found role=" + roles[r]);
groups[0].addMember(role);
}
return groups;
} catch (NamingException e) {
log.error("Failed to obtain groups for user=" + super.getUsername(), e);
throw new LoginException(e.toString(true));
}
}
/**
* Get the password of the current user by querying the userPathPrefix + '/' + super.getUsername() JNDI location.
*/
@Override
protected String getUsersPassword() throws LoginException {
try {
InitialContext ctx = new InitialContext();
String userPath = userPathPrefix + '/' + super.getUsername();
log.info("Getting password for user=" + super.getUsername());
String passwd = (String) ctx.lookup(userPath);
log.info("Found password=" + passwd);
return passwd;
} catch (NamingException e) {
log.error("Failed to obtain password for user=" + super.getUsername(), e);
throw new LoginException(e.toString(true));
}
}
}
例16.23 新規されたカスタムログインモジュールが含まれる security-ex2 セキュリティードメインの定義
/subsystem=security/security-domain=security-ex2/:add
/subsystem=security/security-domain=security-ex2/authentication=classic:add
/subsystem=security/security-domain=security-ex2/authentication=classic/login-module=ex2/:add(\
flag=required,\
code=org.jboss.book.security.ex2.JndiUserAndPassLoginModule,\
module-options=[("userPathPrefix"=>"/security/store/password"),\
("rolesPathPrefix"=>"/security/store/roles")]\
)
ユーザーのサーバー側認証に
JndiUserAndPassLoginModule カスタムログインモジュールを使用することは、セキュリティードメイン例のログイン設定によって判断されます。EJB JAR META-INF/jboss-ejb3.xml 記述子はセキュリティードメインを設定します。Web アプリケーションでは、これは WEB-INF/jboss-web.xml ファイルの一部になります。
例16.24 jboss-ejb3.xml の例
<?xml version="1.0"?>
<jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:s="urn:security" version="3.1" impl-version="2.0">
<assembly-descriptor>
<s:security>
<ejb-name>*</ejb-name>
<s:security-domain>security-ex2</s:security-domain>
</s:security>
</assembly-descriptor>
</jboss:ejb-jar>
例16.25 jboss-web.xml example
<?xml version="1.0"?>
<jboss-web>
<security-domain>security-ex2</security-domain>
</jboss-web>