web-dev-qa-db-ja.com

javax.security.auth.login.LoginException:SomeLogin用に設定されたLoginModuleがありません

さて、サーブレット(EclipseのTomcat 7で実行)のJAAS認証を作成しようとしていますが、このエラーが発生しています。

彼は完全なスタックトレースです: '`

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)

`

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" />

Jaas.configで(Eclipseの「実行構成」の引数に正しいパスを追加したため、Tomcatが正しく検出したと確信しています):

  GdiaLogin {
    org.ktu.gdia.core.security.GdiaLoginModule required debug=true;
};

私はjaas.configに何か間違っている必要があると仮定しています...

私のログインモジュールは、ここで提供する必要があるかどうかはわかりませんが、これまで私が従ってきたチュートリアルからはほぼまっすぐです。

    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;
  }

}

編集:Eclipseの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"

上手?何か案は?

15
Arturas M

http://Tomcat.Apache.org/Tomcat-7.0-doc/realm-howto.html#JAASRealm

Java)のlogin.configファイルを設定し、JVMに場所を指定して、たとえば環境変数Java_OPTS=$Java_OPTS -Djava.security.auth.login.config=$CATALINA_BASE/conf/jaas.configを設定して、Tomcatにその場所を指示する必要があります。

追加

Windowsの場合はstartup.batを開き、次の行を追加します。okHomeの後にset Java_OPTS=%Java_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config

例えば.

:okHome
set Java_OPTS=%Java_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config
set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"
21
Michael

少し遅い答えですが、Eclipse内でJAASカスタムモジュールを有効にするのと同じ問題がある場合:起動引数でjaas.configファイルの場所をTomcatに渡す必要があります。 Eclipseでそれを行う方法は次のとおりです。

  1. サーバータブのTomcatインスタンスをダブルクリックします
  2. 「起動設定を開く」をクリックします
  3. [引数]タブには、VM引数入力テキストがあります。
  4. パラメーターを追加します:-Djava.security.auth.login.config = ""、つまり:

    -Djava.security.auth.login.config = "D:\ Tomcat\7.0.50"\conf\jaas.config "

  5. [適用]をクリックし、[OK]をクリックしてサーバーを再起動します
2
Pantelis

Tomcat 7をサービスとして実行している場合は、.batファイルを使用できません(呼び出されません)。

ただし、/ binディレクトリにある.EXE Tomcat7w.exeを実行できます。 Javaタブ。

1
Robert_T_Taylor

私はまったく同じ問題を抱えていました:

javax.security.auth.login.LoginException: No LoginModules configured for OwnModule

しかし、jaas.configファイルへのパスは正しいものでした。確かに、jaas.configで構文を間違えたときに例外が発生したためです。

Java.io.IOException: Configuration Error:

エンコーディングの変更 file "jaas.config"でこれを解決しました!最初にこのファイルをUTF-8で作成してから、例外について言及しました。エンコードをANSIに変更したとき、問題なく実行されていました!ちょっとおかしい。

1
Radek