I work with LDAP in forest architecture (all servers and my server are windows). I bind to AD using NTLM authentication.
I have a JAVA code that performs operations with an LDAP server.
The code is wrapped like a tomcat servlet.
When you directly run the JAVA code (just executing the LDAP authentication code as an application), the binding works both with the local domain (local domain = I logged in to Windows and started this process with the user of this domain) and foreign domains.
When running JAVA code as a servlet, binding works and authenticates users from one domain, but does not work, if I try to authenticate users from another domain, this will not work (it will only work if you restart tomcat).
I get an exception:
GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))]]
I mentioned that this is the same code with the same configurations and the same krb5 file.
Edit: Additional Information:
This is my code:
public void func(String realm, String kdc) { try { URL configURL = getClass().getResource("jaas_ntlm_configuration.txt"); System.setProperty("java.security.auth.login.config", configURL.toString()); System.setProperty("java.security.krb5.realm", realm); System.setProperty("java.security.krb5.kdc",kdc); // If the application is run on NT rather than Unix, use this name String loginAppName = "MyConfig"; // Create login context LoginContext lc = new LoginContext(loginAppName, new SampleCallbackHandler()); // Retrieve the information on the logged-in user lc.login(); // Get the authenticated subject Subject subject = lc.getSubject(); System.out.println(subject.toString()); Subject.doAs(subject, new JndiAction(new String[] { "" })); } catch (LoginException e) { e.printStackTrace(); } } class JndiAction implements java.security.PrivilegedAction { private String[] args; public JndiAction(String[] origArgs) { this.args = (String[])origArgs.clone(); } public Object run() { performJndiOperation(args); return null; } private static void performJndiOperation(String[] args) { // Set up environment for creating initial context Hashtable env = new Hashtable(11); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // Must use fully qualified hostname env.put(Context.PROVIDER_URL, "ldap://server:389"); // Request the use of the "GSSAPI" SASL mechanism // Authenticate by using already established Kerberos credentials env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI"); try { // Create the initial context DirContext ctx = new InitialLdapContext(env, null); // Close the context when we're done ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } }
And the jaas_ntlm_configuration.txt file contains:
MyConfig { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true doNotPrompt=false; };
My krb5.conf file:
#
I added the following java options:
-Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.conf="krb5.conf" -Dsun.security.krb5.debug=true
If I call func ("SUB * .DOMAIN.COM", "DDC.SUB * .DOMAIN.COM") always with the same subdomain, it will work, but if I call with one subdomain and then with another, the second one will not will succeed.
Additional Information:
Here is the result with krb5.debug = true:
java -Xmx100m -cp gssapi_test.jar -Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.krb5.conf="krb5.conf" -Dsun.security.krb5.debug=true gssapitest.myTest my_config.txt 2 users provided. Performing authentication
What can I do? Am I something wrong?
Thanks.