Pour un serveur Liberty, plusieurs points de plug-in JAAS (Java™ Authentication and Authorization Service)
existent pour la configuration de connexions système. Liberty utilise des configurations de connexion système pour authentifier les demandes entrantes. Vous pouvez développer
un ou plusieurs modules de connexion JAAS personnalisés et les brancher aux points appropriés de la configuration
de connexion système afin d'ajouter des informations à l'objet Subject.
Pourquoi et quand exécuter cette tâche
Les configurations de connexion d'application sont appelées par les applications Servlet
pour obtenir un sujet (objet Subject) constitué d'informations d'authentification spécifiques. Lorsque vous écrivez un module de connexion qui se branche à une configuration de connexion système
ou de connexion d'application Liberty, vous devez développer une logique de configuration de connexion qui détecte des informations spécifiques et sait comment les utiliser. Pour plus d'informations, voir Configuration JAAS et
Modules de connexion JAAS.
Pour développer votre propre module de connexion JAAS
en vue de le brancher dans une configuration de connexion système, lisez la procédure ci-après et
suivez les étapes auxquelles elle renvoie :
Procédure
- Comprendre les rappels utilisables et leur principe de fonctionnement.
Voir Développement de modules de connexion personnalisés pour une configuration de connexion système pour JAAS pour plus d'informations sur les rappels utilisables.
Remarque : Liberty prend en charge uniquement les rappels suivants :
callbacks[0] = new javax.security.auth.callback.NameCallback("Username: ");
callbacks[1] = new javax.security.auth.callback.PasswordCallback("Password: ", false);
callbacks[2] = new com.ibm.websphere.security.auth.callback.WSCredTokenCallbackImpl("Credential Token: ");
callbacks[3] = new com.ibm.websphere.security.auth.callback.WSServletRequestCallback("HttpServletRequest: ")
callbacks[4] = new com.ibm.websphere.security.auth.callback.WSServletResponseCallback("HttpServletResponse: ");
callbacks[5] = new com.ibm.websphere.security.auth.callback.WSAppContextCallback("ApplicationContextCallback: ");
callbacks[6] = new WSRealmNameCallbackImpl("Realm Name: ", default_realm);
callbacks[7] = new WSX509CertificateChainCallback("X509Certificate[]: ");
callbacks[8] = wsAuthMechOidCallback = new WSAuthMechOidCallbackImpl("AuthMechOid: ");
- Comprendre les variables d'état partagé et leur principe de fonctionnement.
Pour accéder aux objets que le
WebSphere Application Server Traditional crée au cours d'une connexion, reportez-vous aux variables d'état partagé ci-après. Pour plus d'informations sur ces variables, voir la sous-rubrique
sur les
"interfaces de programmation de système" de la rubrique
Interfaces de programmation (API)- com.ibm.wsspi.security.auth.callback.Constants.WSPRINCIPAL_KEY
- Spécifie un d'objet d'une classe implémentant l'interface java.security.Principal. Cette variable d'état partagé est seulement fournie ici pour être lue.
N'affectez pas de valeur à cette variable dans l'état partagé pour les modules de connexion personnalisés.
Le module de connexion par défaut définit cette variable.
- com.ibm.wsspi.security.auth.callback.Constants.WSCREDENTIAL_KEY
- Spécifie l'objet com.ibm.websphere.security.cred.WSCredential. Cette variable d'état partagé est seulement fournie ici pour être lue. N'affectez pas de valeur à cette variable dans l'état partagé pour les modules de connexion personnalisés.
Sa valeur
sera fixée par le module de connexion par défaut.
- com.ibm.wsspi.security.auth.callback.Constants.WSSSOTOKEN_KEY
- Spécifie l'objet com.ibm.wsspi.security.token.SingleSignonToken. N'affectez pas de valeur à cette variable dans l'état partagé pour les modules de connexion personnalisés. Le module de connexion par défaut définit cette variable.
- Facultatif : Comprendre l'utilisation des tables de hachage pour les modules de connexion JAAS personnalisés dans Liberty. Voir Module de connexion par table de hachage pour plus de détails.
- Développer un exemple de module de connexion personnalisé en utilisant des rappels et des variables d'état partagé.
Vous pouvez vous inspirer de
l'exemple suivant pour apprendre à utiliser certains des rappels (callbacks) et
des variables d'état partagé.
public class CustomCallbackLoginModule implements LoginModule {
protected Map<String, ?> _sharedState;
protected Subject _subject = null;
protected CallbackHandler _callbackHandler;
private final String customPrivateCredential = "CustomLoginModuleCredential";
/**
* Initialization of login module
*/
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
_sharedState = sharedState;
_subject = subject;
_callbackHandler = callbackHandler;
}
public boolean login() throws LoginException {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
_subject.getPrivateCredentials().add(customPrivateCredential);
return null;
}
});
} catch (PrivilegedActionException e) {
throw new LoginException(e.getLocalizedMessage());
}
String username = null;
char passwordChar[] = null;
byte[] credToken = null;
HttpServletRequest request = null;
HttpServletResponse response = null;
Map appContext = null;
String realm = null;
String authMechOid = null;
java.security.cert.X509Certificate[] certChain = null;
NameCallback nameCallback = null;
PasswordCallback passwordCallback = null;
WSCredTokenCallbackImpl wsCredTokenCallback = null;
WSServletRequestCallback wsServletRequestCallback = null;
WSServletResponseCallback wsServletResponseCallback = null;
WSAppContextCallback wsAppContextCallback = null;
WSRealmNameCallbackImpl wsRealmNameCallback = null;
WSX509CertificateChainCallback wsX509CertificateCallback = null;
WSAuthMechOidCallbackImpl wsAuthMechOidCallback = null;
Callback[] callbacks = new Callback[9];
callbacks[0] = nameCallback = new NameCallback("Username: ");
callbacks[1] = passwordCallback = new PasswordCallback("Password: ", false);
callbacks[2] = wsCredTokenCallback = new WSCredTokenCallbackImpl("Credential Token: ");
callbacks[3] = wsServletRequestCallback = new WSServletRequestCallback("HttpServletRequest: ");
callbacks[4] = wsServletResponseCallback = new WSServletResponseCallback("HttpServletResponse: ");
callbacks[5] = wsAppContextCallback = new WSAppContextCallback("ApplicationContextCallback: ");
callbacks[6] = wsRealmNameCallback = new WSRealmNameCallbackImpl("Realm name:");
callbacks[7] = wsX509CertificateCallback = new WSX509CertificateChainCallback("X509Certificate[]: ");
callbacks[8] = wsAuthMechOidCallback = new WSAuthMechOidCallbackImpl("AuthMechOid: ");
try {
_callbackHandler.handle(callbacks);
} catch (Exception e) {
// handle exception
}
if (nameCallback != null)
username = nameCallback.getName();
if (passwordCallback != null)
passwordChar = passwordCallback.getPassword();
if (wsCredTokenCallback != null)
credToken = wsCredTokenCallback.getCredToken();
if (wsServletRequestCallback != null)
request = wsServletRequestCallback.getHttpServletRequest();
if (wsServletResponseCallback != null)
response = wsServletResponseCallback.getHttpServletResponse();
if (wsAppContextCallback != null)
appContext = wsAppContextCallback.getContext();
if (wsRealmNameCallback != null)
realm = wsRealmNameCallback.getRealmName();
if (wsX509CertificateCallback != null)
certChain = wsX509CertificateCallback.getX509CertificateChain();
if (wsAuthMechOidCallback != null)
authMechOid = wsAuthMechOidCallback.getAuthMechOid();
_subject.getPrivateCredentials().add("username = " + username);
_subject.getPrivateCredentials().add("password = " + String.valueOf(passwordChar));
_subject.getPrivateCredentials().add("realm = " + realm);
_subject.getPrivateCredentials().add("authMechOid = " + authMechOid.toString());
return true;
}
public boolean commit() throws LoginException {
return true;
}
public boolean abort() {
return true;
}
public boolean logout() {
return true;
}
}
- Facultatif : Développer un exemple de module de connexion personnalisé en utilisant le procédé de connexion avec table de hachage.
Vous pouvez vous inspirer de
l'exemple suivant pour apprendre à utiliser la connexion avec table de hachage.
package com.ibm.websphere.security.sample;
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 com.ibm.wsspi.security.token.AttributeNameConstants;
/**
* Custom login module that adds another PublicCredential to the subject
*/
@SuppressWarnings("unchecked")
public class CustomHashtableLoginModule implements LoginModule {
protected Map<String, ?> _sharedState;
protected Map<String, ?> _options;
/**
* Initialization of login module
*/
public void initialize(
Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
_sharedState = sharedState;
_options = options;
}
public boolean login() throws LoginException {
try {
java.util.Hashtable<String, Object> customProperties = (java.util.Hashtable<String, Object>)
_sharedState.get(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY);
if (customProperties == null) {
customProperties = new java.util.Hashtable<String, Object>();
}
customProperties.put(AttributeNameConstants.WSCREDENTIAL_USERID, "userId");
// Sample of creating custom cache key
customProperties.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY, "customCacheKey");
/*
* Sample for creating user ID and security name
* customProperties.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, "userId");
* customProperties.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, "securityName");
* customProperties.put(AttributeNameConstants.WSCREDENTIAL_REALM, "realm");
* customProperties.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, "groupList");
*/
/*
* Sample for creating user ID and password
* customProperties.put(AttributeNameConstants.WSCREDENTIAL_USERID, "userId");
* customProperties.put(AttributeNameConstants.WSCREDENTIAL_PASSWORD, "password");
*/
Map<String, java.util.Hashtable> mySharedState = (Map<String, java.util.Hashtable>) _sharedState;
mySharedState.put(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY, customProperties);
} catch (Exception e) {
throw new LoginException("LoginException: " + e.getMessage());
}
return true;
}
public boolean commit() throws LoginException {
return true;
}
public boolean abort() {
return true;
}
public boolean logout() {
return true;
}
}
Que faire ensuite
Ajoutez votre module de connexion personnalisé aux configurations de connexion
système JAAS WEB_INBOUND et DEFAULT, dans le fichier server.xml. Placez la classe du module de connexion personnalisé dans un fichier JAR, par exemple
customLoginModule.jar, puis mettez le fichier JAR à disposition sur le serveur Liberty. Voir Configuration d'un module de connexion personnalisé JAAS pour Liberty.