My mongodb is set up to use Kerberos and everything is working fine when I access the database from the shell.

Now I need my Java applications to also connect to the databases, authenticating using Kerberos. Apart of the few lines in http://docs.mongodb.org/ecosystem/tutorial/authenticate-with-java-driver/ I have not found how to make this work.

My main use case is harder than described on that page. I have a tomcat server that serves multiple users - so I need the user to log into the application and supply their principal name and password and I want the Java server to authenticate to the KDC and then use the provided ticket to mongodb -- I can't find a way to do this.

If this is not possible and I have to use a separate tomcat server per user, I assume I can do a kinit and then start tomcat? That would mean that each user would have to run their own server. Not that great - but even here - what do I need to do so that the Java process uses whatever kinit puts in the session.

Any other suggestion on how to do this is also greatly appreciated (E.g. can my servlet running in tomcat get something from the user's browser that is a Kerberos ticket? Without rocket science and expensive licenses..). All I want to do is allow people to login to mongodb using Kerberos credentials -- but through a Java app.

有帮助吗?

解决方案

The 10gen/MongoDB provided Java Driver only support Kerberos authentication via kinit. To have the Tomcat instances authenticate with different principals you will not only need to run different instances but those instances will have to be running under different system accounts. This is due to kinit savint the credentials/tickets in a file in the system's temporary directory. This is why you can kinit in one terminal and then login to servers from a different terminal. The credentials are global for the account and realistically you can only have 1 principal being used for the account at one time. This is one of many reasons we find kinit to be unsatisfactory to running services.

I work on the Asynchronous Java Driver and it supports 3 mechanisms for providing credentials for Kerberos authentication:

  1. Username and password.
  2. Key Tab files.
  3. kinit.

Either the username or key tab file should work for your use case. The details of the kerberos support are available here. From that page, authentication can be as simple as:

MongoClientConfiguration config = new MongoClientConfiguration("mongodb://locahost:27017/");

char[] password = new char[] { 's', 'u', 'p', 'e', 'r', 
                               's', 'e', 'c', 'r', 'e', 't' };
config.addCredential(Credential.builder()
              .userName("<user>@<REALM>")
              .password(password)
              .kerberos());
Arrays.fill( password, ' ' );

A few of notes:

  1. Getting Java to use kerberos is not hard but it is finicky. Make sure you have read the Java Kerberos Configuration guide and understand what needs to be done on the system and to the JVM to get it to work. There are several ways to getting a working setup. Which one you choose it dependent on your needs and system configuration.
  2. You will need the driver's extensions jar to use kerberos authentication. Again, contact me via the link at the bottom of the kerberos help to get a copy.
  3. We have not actually tested the driver using multiple credentials within a single JVM. It should work but without testing it you never know what you may run into. We will be happy work with you to get it working if you do run into any issues.

HTH, Rob.

其他提示

A nice trick that works with MongoDB Java driver is using system's Kerberos tickets. So, you can use something like:

sudo -u tomcat kinit application/username@REALM

Now, depending on KDC's configuration you might need to renew credentials from time to time, for that use:

sudo -u tomcat kinit -R

As stated already, Kerberos support is only available for MongoDB Enterprise, which can be downloaded from MongoDB website.

If you want to configure multiple kerberos with different kt files using GSSAPI auth.

We can do following,

com.sun.security.jgss.initiate {
  // first connection details
  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=false
  doNotPrompt=true
  useKeyTab=true
  keyTab="file:C:/blah/blah/dummy.keytab"
  principal="dummy@SOME.REALM"
  debug=false;

  // second connection details
  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=false
  doNotPrompt=true
  useKeyTab=true
  keyTab="file:C:/blah/blah/dummy2.keytab"
  principal="dummy2@SOME.REALM"
  debug=false;
};

If you wanna mix multiple different services,

// First component details HBASE / IMPALA / MongoDb with two diff kerberos connection details
com.sun.security.jgss.initiate {
  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=false
  doNotPrompt=true
  useKeyTab=true
  keyTab="file:C:/blah/blah/dummy.keytab"
  principal="dummy@SOME.REALM"
  debug=false;

  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=false
  doNotPrompt=true
  useKeyTab=true
  keyTab="file:C:/blah/blah/dummy2.keytab"
  principal="dummy2@SOME.REALM"
  debug=false;
};

// Kafka with two diff kerberos connection details
SimpleClient {
  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=false
  doNotPrompt=true
  useKeyTab=true
  keyTab="file:C:/blah/blah/dummy.keytab"
  principal="dummy@SOME.REALM"
  debug=false;

  com.sun.security.auth.module.Krb5LoginModule required
  useTicketCache=false
  doNotPrompt=true
  useKeyTab=true
  keyTab="file:C:/blah/blah/dummy2.keytab"
  principal="dummy2@SOME.REALM"
  debug=false;
};
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top