システム・プログラミング・インターフェースを使用すると、Microsoft Active Directory から得られるエンド・ユーザーの ID から、WebSphere Application Server セキュリティー・レジストリーで使用される ID への任意のマッピングをインプリメントすることにより、Simple and Protected GSS-API Negotiation Mechanism (SPNEGO) トラスト・アソシエーション・インターセプター (TAI) の動作をカスタマイズできます。
この簡単な SPNEGO TAI のデプロイメントを使用する必要はありません。WebSphere Application Server は、Microsoft Active Directory の代わりに、別のレジストリー (ローカル OS、LDAP、カスタム・レジストリーなど) を使用することができます。 WebSphere Application Server が Microsoft Active Directory とは異なるレジストリーを使用している場合は、Microsoft Windows ユーザー ID から WebSphere Application Server ユーザー ID へのマッピングが必要です。
package com.ibm.ws.security.server.lm; import java.util.Map; import java.lang.reflect.Array; import javax.security.auth.Subject; import javax.security.auth.callback.*; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import javax.security.auth.kerberos.*; import com.ibm.websphere.security.auth.WSLoginFailedException; import com.ibm.wsspi.security.token.AttributeNameConstants; /** * * @author IBM Corporation * @version 1.0 * @since 1.0 * */ public class sampleSpnegoMappingLoginModule implements LoginModule { /* * * Constant that represents the name of this mapping module. Whenever this sample * code is used to create a class with a different name, this value should be changed. * */ private final static String MAPPING_MODULE_NAME = "com.ibm.websphere.security.sampleSpnegoMappingLoginModule"; private String mapUid = null; /** * Construct an uninitialized WSLoginModuleImpl object. */ public sampleSpnegoMappingLoginModule() { debugOut("sampleSpnegoMappingLoginModule() entry"); debugOut("sampleSpnegoMappingLoginModule() exit"); } /** * Initialize this login module. * * * This is called by the LoginContext after this login module is * instantiated. The relevant information is passed from the LoginContext * to this login module. If the login module does not understands any of the data * stored in the sharedState and options parameters, * they can be ignored. * * * @param subject The subject to be authenticated. * @param callbackHandler * A CallbackHandler for communicating with the end user to gather login information (e.g., username and password). * @param sharedState * The state shared with other configured login modules. * @param options The options specified in the login configuration for this particular login module. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { debugOut("initialize(subject = ¥"" + subject.toString() + "¥", callbackHandler = ¥"" + callbackHandler.toString() + "¥", sharedState = ¥"" + sharedState.toString() + "¥", options = ¥"" + options.toString() + "¥")"); this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; debug = "true".equalsIgnoreCase((String)this.options.get("debug")); debugOut("initialize() exit"); } /** * * Method to authenticate a Subject (phase 1). * * * * This method authenticates a Subject. It uses CallbackHandler to gather * the Subject information, like username and password for example, and verify these * information. The result of the authentication is saved in the private state within * this login module. * * * @return true if the authentication succeeded, or false * if this login module should be ignored. * @exception LoginException * If the authentication fails. */ public boolean login() throws LoginException { debugOut("sampleSpnegoMappingLoginModule.login() entry"); boolean succeeded = false; java.util.Set krb5Principals= subject.getPrincipals(KerberosPrincipal.class); java.util.Iterator krb5PrincIter = krb5Principals.iterator(); while (krb5PrincIter.hasNext()) { Object princObj = krb5PrincIter.next(); debugOut("Kerberos principal name: "+ princObj.toString()); if (princObj != null && princObj.toString().equals("utle@WSSEC.AUSTIN.IBM.COM")){ mapUid = "user1"; debugOut("mapUid: "+mapUid); java.util.Hashtable customProperties = (java.util.Hashtable) sharedState.get(AttributeNameConstants.WSCREDENTIAL_USERID); if (customProperties == null) { customProperties = new java.util.Hashtable(); } customProperties.put(AttributeNameConstants.WSCREDENTIAL_USERID, mapUid); debugOut("Add a mapping user ID to Hashtable, mapping ID = "+mapUid); } debugOut("login() custom properties = " + customProperties); } } succeeded = true; debugOut("sampleSpnegoMappingLoginModule.login() exit"); return succeeded; } /** * * Method to commit the authentication result (phase 2). * * * * This method is called if the LoginContext's overall authentication * succeeded (the revelant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL login module * succeeded). * * * @return true if the commit succeeded, or false * if this login module should be ignored. * @exception LoginException * If the commit fails. */ public boolean commit() throws LoginException { debugOut("commit()"); debugOut("commit()"); return true; } /** * Method to abort the authentication process (phase 2). * * * This method is called if the LoginContext's overall authentication * failed (the revelant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL login module * did not succeed). * * * * If this login module's authentication attempt succeeded, then this method cleans * up the previous state saved in phase 1. * * * @return true if the abort succeeded, or false * if this login module should be ignored. * @exception LoginException * If the abort fails. */ public boolean abort() throws LoginException { debugOut("abort() entry"); debugOut("abort() exit"); return true; } /** * Method which logs out a Subject. * * @return true if the logout succeeded, or false * if this login module should be ignored. * @exception LoginException * If the logout fails. */ public boolean logout() throws LoginException { debugOut("logout() entry"); debugOut("logout() exit"); return true; } private void cleanup() { debugOut("cleanup() entry"); debugOut("cleanup() exit"); } /* * * Private method to print trace information. This implementation uses System.out * to print trace information to standard output, but a custom tracing system can * be implemented here as well. * */ private void debugOut(Object o) { System.out.println("Debug: " + MAPPING_MODULE_NAME); if (o != null) { if (o.getClass().isArray()) { int length = Array.getLength(o); for (int i = 0; i < length; i++) { System.out.println("¥t" + Array.get(o, i)); } } else { System.out.println("¥t" + o); } } } private Subject subject; private CallbackHandler callbackHandler; private Map sharedState; private Map options; protected boolean debug = false; }