I am trying to create JAAS Authentication for my servlet (Using tomcat 8.5 in eclipse). I got the error given below when i try to login.

StackTrace:

Apr 29, 2019 5:06:31 PM org.apache.catalina.realm.JAASRealm authenticate
SEVERE: Unexpected error
javax.security.auth.login.LoginException: No LoginModules configured for UserAndPasswordPrincipal
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:400)
at org.apache.catalina.realm.JAASRealm.authenticate(JAASRealm.java:335)
at org.apache.catalina.authenticator.FormAuthenticator.doAuthenticate(FormAuthenticator.java:264)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:575)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:660)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

ProjectName : UserAndPasswordPrinciple

In server.xml

 <Realm className="com.princi.jaas.newJAASRealm" 
appName="UserAndPasswordPrincipal"
userClassNames="com.princi.jaas.UserPrincipal"
roleClassNames="com.princi.jaas.RolePrincipal" ></Realm>

In %calatina%/conf/jaas.config

 UserAndPasswordPrincipal {
    com.princi.jaas.MyLoginModule required debug=true;
};

I am confused where to give jaas.config file location so i gave it in both

java.security and startup.bat

In C:\Program Files\Java\jdk1.8.0_201\jre\lib\security\java.security

JAVA_OPTS=$JAVA_OPTS -Djava.security.auth.login.config=$CATALINA_BASE/conf/jaas.config

In startup.bat

 .....

:okHome
set JAVA_OPTS=%JAVA_OPTS% -Djava.security.auth.login.config=%CATALINA_HOME%\conf\jaas.config

Created a jar file and uploaded my classes

CatalinaHome/lib/MyLoginModule.jar contains

newJAASRealm extends JAASRealm
MyLoginModule implements LoginModule
UserPrincipal extends Principal
RolePrincipal extends Principal

MyLoginModule.java

package com.princi.jaas;

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;

public class MyLoginModule implements LoginModule {

 private CallbackHandler handler;
  private Subject subject;
  private UserPrincipal userPrincipal;
  private RolePrincipal rolePrincipal;
  private String login;
  private List<String> userGroups;

  @Override
  public void initialize(Subject subject,
      CallbackHandler callbackHandler,
      Map<String, ?> sharedState,
      Map<String, ?> options) {

    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());
  if (name != null &&
          name.equals("user123") &&
          password != null &&
          password.equals("pass123")) {


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

}

UserPrincipal.java

package com.princi.jaas;

import java.security.Principal;

public class UserPrincipal implements Principal {

private String name;

  public UserPrincipal(String name) {
    super();
    this.name = name;
  }

  public void setName(String name) {
    this.name = name;
  }
@Override
public String getName() {

    return name;
}

}

RolePrincipal.java

package com.princi.jaas;

import java.security.Principal;

public class RolePrincipal implements Principal {

  private String name;

  public RolePrincipal(String name) {
    super();
    this.name = name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String getName() {
    return name;
  }

}

Simply overriden JAASRealm to check whether it is working or not

newJAASRealm.java

package com.princi.jaas;

import org.apache.catalina.realm.JAASRealm;

public class newJAASRealm extends JAASRealm{

}

0 Answers