Vous pouvez mapper le nom de principal client Kerberos sur
l'ID du registre d'utilisateurs WebSphere à la fois pour
l'authentification SPNEGO (Simple and Protected GSS-API Negotiation)
et l'authentification Kerberos.
Pourquoi et quand exécuter cette tâche
Utilisez le module de connexion personnalisé JAAS (Java Authentication and Authorization Service) pour effectuer n'importe quel mappage personnalisé d'un nom de principal Kerberos client à l'identité du registre d'utilisateurs WebSphere. Le module de connexion personnalisé JAAS est un mécanisme de plug-in
défini pour les requêtes d'authentification entrantes de
WebSphere
Application Server. Si le mécanisme d'authentification actif est LTPA, le module de connexion personnalisé JAAS est inséré immédiatement avant ltpaLoginModule.
Si le mécanisme d'authentification actif est Kerberos, le module de connexion personnalisé JAAS est inséré immédiatement avant WSKrb5LoginModule.
Le module de connexion personnalisé JAAS récupère un nom de principal Kerberos client dans javax.security.auth.Subject en utilisant la méthode subject.getPrivateCredentials(KRBAuthnToken.class).
Le module de connexion personnalisé JAAS mappe le nom de principal Kerberos client
vers l'identité du registre d'utilisateurs WebSphere et insère l'identité de mappage dans la propriété de table de hachage com.ibm.wsspi.security.cred.userId.
wsMapDefaultInboundLoginModule utilise alors l'identité mappée pour créer un objet WSCredential.
Remarque : Pour l'authentification Web SPNEGO, le module de connexion personnalisé peut également fournir l'ensemble complet de propriétés de sécurité de javax.security.auth.Subject dans l'élément com.ibm.wsspi.security.tai.TAIResult afin de vérifier intégralement l'identité mappée. Lorsque l'identité est complètement vérifiée, wsMapDefaultInboundLoginModule mappe ces propriétés de sécurité sur un objet WSCredential.
- Reportez-vous à l'exemple de module de connexion personnalisé suivant :
package com.ibm.websphere.security;
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;
import com.ibm.wsspi.wssecurity.platform.token.KRBAuthnToken;
/**
*
* @author IBM Corporation
* @version 1.0
* @since 1.0
*
*/
public class sampleSpnegoMappingLoginModule implements LoginModule {
/*
*
* Constante qui représente le nom de ce module de mappage. A chaque fois que cet exemple
* de code est utilisé pour créer une classe d'un nom différent, cette valeur doit être modifiée.
*
*/
private final static String MAPPING_MODULE_NAME = "com.ibm.websphere.security.sampleSpnegoMappingLoginModule";
private String mapUid = null;
/**
* Construisez un objet WSLoginModuleImpl non initialisé.
*/
public sampleSpnegoMappingLoginModule() {
debugOut("sampleSpnegoMappingLoginModule() entry");
debugOut("sampleSpnegoMappingLoginModule() exit");
}
/**
* Initialisez ce module de connexion.
*
*
* Il est appelé par LoginContext une fois que ce module de connexion a été
* instancié. Les informations appropriées sont transmises à partir de LoginContext
* vers ce module de connexion. Si le module de connexion ne comprend pas certaines des données
* stockées dans sharedState et dans les paramètres d'option,
* elles peuvent être ignorées.
*
*
* @param subject Le sujet à authentifier
* @param callbackHandler
* A CallbackHandler for communicating with the end user to gather login information (par exemple, nom d'utilisateur et mot de passe).
* @param sharedState
* L'état partagé avec d'autres modules de connexion configurés.
* @param options Les options spécifiées dans la configuration de connexion pour ce module de connexion.
*/
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");
}
/**
*
* Méthode d'authentification d'un sujet (phase 1).
*
*
*
* Cette méthode authentifie un sujet. Elle utilise CallbackHandler pour rassembler
* des informations de sujet, telles le nom d'utilisateur et le mot de passe, par exemple et vérifier ces
* informations. Le résultat de l'authentification est sauvegardé à l'état privé dans
* ce module de connexion.
*
*
* @return true si l'authentification aboutit ou false
* si ce module de connexion doit être ignoré.
* @exception LoginException
* Si l'authentification n'aboutit pas.
*/
public boolean login() throws LoginException
{
debugOut("sampleSpnegoMappingLoginModule.login() entry");
boolean succeeded = false;
KRBAuthnToken krbAuthnToken = null;;
java.util.Set krb5Principals= subject.getPrivateCredentials(KRBAuthnToken.class);
java.util.Iterator krb5PrincIter = krb5Principals.iterator();
while (krb5PrincIter.hasNext()) {
krbAuthnToken = (KRBAuthnToken)krb5PrincIter.next();
String kerbPrincipal = (String) krbAuthnToken.getTokenPrincipal() + "@" + krbAuthnToken.getTokenRealm();
debugOut("Kerberos principal name: "+ kerbPrincipal.toString());
if (kerbPrincipal!= null && kerbPrincipal.equals("utle@WSSEC.AUSTIN.IBM.COM")){
mapUid = "user1";
debugOut("mapUid: "+mapUid);
java.util.Hashtable customProperties = (java.util.Hashtable)
sharedState.get(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY);
if (customProperties == null) {
customProperties = new java.util.Hashtable();
}
succeeded = true;
customProperties.put(AttributeNameConstants.WSCREDENTIAL_USERID, mapUid);
Map<String,java.util.Hashtable>mySharedState=(Map<String,java.
util.Hashtable>)sharedState;
mySharedState.put(AttributeNameConstants.WSCREDENTIAL_PROPERTIES_KEY,
customProperties);
debugOut("Add a mapping user ID to Hashtable, mapping ID = "+mapUid);
debugOut("login() custom properties = " + customProperties);
}
}
succeeded = true;
debugOut("sampleSpnegoMappingLoginModule.login() exit");
return succeeded;
}
/**
*
* Méthode de validation du résultat d'authentification (phase 2).
*
*
*
* Cette méthode est appelée si l'authentification générale de LoginContext
* a abouti (le module de connexion approprié REQUIRED, REQUISITE, SUFFICIENT et OPTIONAL
* a abouti).
*
*
* @return true si l'authentification a abouti, ou false
* si ce module de connexion doit être ignoré.
* @exception LoginException
* si la validation échoue.
*/
public boolean commit() throws LoginException
{
debugOut("commit()");
debugOut("commit()");
return true;
}
/**
* Méthode permettant d'abandonner le processus d'authentification (phase 2).
*
*
* Cette méthode est appelée si l'authentification générale de LoginContext
* a échoué (le module de connexion approprié REQUIRED, REQUISITE, SUFFICIENT et OPTIONAL
* n'a pas abouti).
*
*
*
* Si cette tentative d'authentification du module de connexion a abouti, alors cette méthode nettoie
* l'état précédent sauvegardé à la phase 1.
*
*
* @return true si l'abandon a abouti, ou false
* si ce module de connexion doit être ignoré.
* @exception LoginException
* si l'abandon échoue.
*/
public boolean abort() throws LoginException {
debugOut("abort() entry");
debugOut("abort() exit");
return true;
}
/**
* Méthode permettant de déconnecter un sujet.
*
* @return true si la déconnexion a abouti, ou false
* si ce module de connexion doit être ignoré.
* @exception LoginException
* si la déconnexion a échoué.
*/
public boolean logout() throws LoginException
{
debugOut("logout() entry");
debugOut("logout() exit");
return true;
}
private void cleanup()
{
debugOut("cleanup() entry");
debugOut("cleanup() exit");
}
/*
*
* Méthode privée permettant d'imprimer les informations de trace. Cette implémentation utilise System.out
* pour imprimer les informations de trace dans la sortie standard, mais un système de traçage personnalisé peut
* être implémenté à cet emplacement également.
*
*/
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;
}
- Pour l'authentification Web SPNEGO sans authentification
Kerberos, ce module de connexion personnalisé JAAS doit au préalable
être inséré immédiatement avant le module ltpaLoginModule dans la
connexion de pile de la configuration de connexion du système pour
WEB_INBOUND, RMI_INBOUND et DEFAULT.
- Pour l'authentification Kerberos, ce module de connexion personnalisé JAAS doit être inséré immédiatement avant le WSKrb5LoginModule pour la configuration de connexion système pour WEB_INBOUND, RMI_INBOUND et DEFAULT.