Eh bien, j'essaie de créer une authentification JAAS pour mon servlet (fonctionnant sur Tomcat 7 dans Eclipse), mais je reçois cette erreur.
C'est la trace complète de la pile: ''
INFO: Starting Servlet Engine: Apache Tomcat/7.0.32
Geg 19, 2013 9:53:08 PM org.Apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Geg 19, 2013 9:53:08 PM org.Apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Geg 19, 2013 9:53:08 PM org.Apache.catalina.startup.Catalina start
INFO: Server startup in 1786 ms
Geg 19, 2013 9:53:30 PM org.Apache.catalina.realm.JAASRealm authenticate
SEVERE: Unexpected error
javax.security.auth.login.LoginException: No LoginModules configured for GdiaLogin
at javax.security.auth.login.LoginContext.init(Unknown Source)
at javax.security.auth.login.LoginContext.<init>(Unknown Source)
at org.Apache.catalina.realm.JAASRealm.authenticate(JAASRealm.Java:392)
at org.Apache.catalina.realm.JAASRealm.authenticate(JAASRealm.Java:332)
at org.Apache.catalina.authenticator.BasicAuthenticator.authenticate(BasicAuthenticator.Java:158)
at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:544)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:168)
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:99)
at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:929)
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:118)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:407)
at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1002)
at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:585)
at org.Apache.Tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.Java:312)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at Java.lang.Thread.run(Unknown Source)
Geg 19, 2013 10:29:20 PM org.Apache.catalina.realm.JAASRealm authenticate
SEVERE: Unexpected error
javax.security.auth.login.LoginException: No LoginModules configured for GdiaLogin
at javax.security.auth.login.LoginContext.init(Unknown Source)
at javax.security.auth.login.LoginContext.<init>(Unknown Source)
at org.Apache.catalina.realm.JAASRealm.authenticate(JAASRealm.Java:392)
at org.Apache.catalina.realm.JAASRealm.authenticate(JAASRealm.Java:332)
at org.Apache.catalina.authenticator.BasicAuthenticator.authenticate(BasicAuthenticator.Java:158)
at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:544)
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:168)
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:99)
at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:929)
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:118)
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:407)
at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1002)
at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:585)
at org.Apache.Tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.Java:312)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at Java.lang.Thread.run(Unknown Source)
"
Dans context.xml:
<Realm className="org.Apache.catalina.realm.JAASRealm"
appName="GdiaLogin"
userClassNames="org.ktu.gdia.core.security.UserPrincipal"
roleClassNames="org.ktu.gdia.core.security.RolePrincipal" />
Dans jaas.config (je suis presque sûr que Tomcat le trouve correctement parce que j'ai ajouté le chemin correct avec des arguments pour "exécuter les configurations" dans Eclipse):
GdiaLogin {
org.ktu.gdia.core.security.GdiaLoginModule required debug=true;
};
Je suppose qu'il doit y avoir quelque chose de mal avec le jaas.config ...
Mon module de connexion, je ne sais pas si je dois le fournir ici, cependant, il est presque directement issu d'un tutoriel que j'ai suivi:
package org.ktu.gdia.core.security;
import Java.io.IOException;
import Java.util.ArrayList;
import Java.util.List;
import Java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import org.ktu.gdia.core.businesslogic.ControllerFactory;
import org.ktu.gdia.core.interfaces.SecurityControllerInterface;
public class GdiaLoginModule implements LoginModule {
private CallbackHandler handler;
private Subject subject;
private UserPrincipal userPrincipal;
private RolePrincipal rolePrincipal;
private String login;
private List<String> userGroups;
private SecurityControllerInterface securityController;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
try {
securityController = ControllerFactory.getInstance().getSecurityController();
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException e) {
throw new RuntimeException("Failed to initialize SecurityController in " + this.getClass().getSimpleName(), e);
}
handler = callbackHandler;
this.subject = subject;
}
@Override
public boolean login() throws LoginException {
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("login");
callbacks[1] = new PasswordCallback("password", true);
try {
handler.handle(callbacks);
String name = ((NameCallback) callbacks[0]).getName();
String password = String.valueOf(((PasswordCallback) callbacks[1])
.getPassword());
// Here we validate the credentials against some
// authentication/authorization provider.
// It can be a Database, an external LDAP,
// a Web Service, etc.
// For this tutorial we are just checking if
// user is "user123" and password is "pass123"
if (securityController.credentialsValid(name, password)) {
// TODO authenticate
login = name;
userGroups = new ArrayList<String>();
userGroups.add("admin");
return true;
}
if (name != null &&
name.equals("user123") &&
password != null &&
password.equals("pass123")) {
// We store the username and roles
// fetched from the credentials provider
// to be used later in commit() method.
// For this tutorial we hard coded the
// "admin" role
login = name;
userGroups = new ArrayList<String>();
userGroups.add("admin");
return true;
}
// If credentials are NOT OK we throw a LoginException
throw new LoginException("Authentication failed");
} catch (IOException e) {
throw new LoginException(e.getMessage());
} catch (UnsupportedCallbackException e) {
throw new LoginException(e.getMessage());
}
}
@Override
public boolean commit() throws LoginException {
userPrincipal = new UserPrincipal(login);
subject.getPrincipals().add(userPrincipal);
if (userGroups != null && userGroups.size() > 0) {
for (String groupName : userGroups) {
rolePrincipal = new RolePrincipal(groupName);
subject.getPrincipals().add(rolePrincipal);
}
}
return true;
}
@Override
public boolean abort() throws LoginException {
return false;
}
@Override
public boolean logout() throws LoginException {
subject.getPrincipals().remove(userPrincipal);
subject.getPrincipals().remove(rolePrincipal);
return true;
}
}
Edit: Mes arguments de configuration d'exécution dans Eclipse pour Tomcat:
-Dcatalina.base="D:\Dropbox\EclipseWorkspace\.metadata\.plugins\org.Eclipse.wst.server.core\tmp7" -Dcatalina.home="D:\Servers\GenTreeUploader_Tomcat7" -Dwtp.deploy="D:\Dropbox\EclipseWorkspace\.metadata\.plugins\org.Eclipse.wst.server.core\tmp7\wtpwebapps" -Djava.endorsed.dirs="D:\Servers\GenTreeUploader_Tomcat7\endorsed" -Djava.security.auth.login.config="D:\Dropbox\EclipseWorkspace\.metadata\.plugins\org.Eclipse.wst.server.core\tmp7\conf\jaas.config"
Bien? Des idées?
Selon http://Tomcat.Apache.org/Tomcat-7.0-doc/realm-howto.html#JAASRealm
Vous devez configurer un fichier login.config pour Java et indiquer à Tomcat où le trouver en spécifiant son emplacement sur la JVM, par exemple en définissant la variable d'environnement: Java_OPTS=$Java_OPTS -Djava.security.auth.login.config=$CATALINA_BASE/conf/jaas.config
Ajouté
Pour Windows, ouvrez startup.bat
Ajoutez la ligne suivante: set Java_OPTS=%Java_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config
après okHome
par exemple.
:okHome
set Java_OPTS=%Java_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config
set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"
Réponse un peu tardive, mais au cas où quelqu'un rencontrerait le même problème lors de l'activation de ses modules personnalisés JAAS dans Eclipse: vous devez transmettre l'emplacement du fichier jaas.config à Tomcat dans ses arguments de démarrage. La façon de le faire dans Eclipse est:
Ajoutez votre paramètre: -Djava.security.auth.login.config = "", c'est-à-dire:
-Djava.security.auth.login.config = "D:\Tomcat\7.0.50"\conf\jaas.config "
Si Tomcat 7 fonctionne en tant que service, vous ne pouvez pas utiliser le fichier .bat (ils ne seront pas appelés).
Cependant, vous pouvez exécuter le .EXE Tomcat7w.exe trouvé dans le répertoire/bin. Vous verrez un panneau avec un Java. Vous pouvez y ajouter des propriétés -D (comme pointer vers votre fichier jaas.config).
J'ai eu exactement le même problème:
javax.security.auth.login.LoginException: No LoginModules configured for OwnModule
mais le chemin d'accès au fichier jaas.config était correct. Je suis sûr, car lorsque j'ai fait une erreur de syntaxe dans jaas.config, j'ai eu une exception:
Java.io.IOException: Configuration Error:
J'ai résolu cela en changer l'encodage fichier "jaas.config"! J'ai d'abord créé ce fichier en UTF-8, puis j'ai mentionné l'exception. Lorsque j'ai changé le codage en ANSI, il fonctionnait sans problème! Un peu fou.