Authentifizierung gegen DomainController

franzy

Aktives Mitglied
Hallo zusammen,

ich möchte mich gegen einen AD Authentifizieren.
Ich habe dazu folgendes Programmiert:

Java:
LoginContext lc;
        
try
{   
    System.setProperty("java.security.krb5.realm", "domaineImDNS.de");
    System.setProperty("java.security.krb5.kdc", "ServerXYZ");

    lc = new LoginContext("", null, new StaticCallbackHandler("adname.dom\\userid", "password""), new StaticConfiguration("com.sun.security.auth.module.Krb5LoginModule"));
    lc.login();

    lc.logout();
}
catch (LoginException le)
{
    throw new ValidationException("Anmeldung fehlgeschlagen: " + le.getMessage(), le);
}
catch (Exception ex)
{
    throw new ValidationException("Anmeldung fehlgeschlagen: " + ex.getMessage(), ex);
}

Wir müssen bei unseren Windows-Anmeldung die Domaine (AD) voranstellen (adname.dom) und dann die userid. Beispiel oben im Quelltext adname.dom\\userid.
(Doppel Backslash sind nur wegen String)

Nur leider funktioniert das nicht.
Wie kann ich die Domaine mitgeben wie wenn ich sie an der Windows-Anmeldung mitgebe.
1614943293331.png

So wie oben gezeigt geht es nicht.

Hat jemand eine Idee?

Besten Dank, grüße franzy
 
K

kneitzel

Gast
Wenn Du die Domain mit angeben musst, dann könntest Du die @ Schreibweise ausprobieren: user@domain ist auch eine gültige Schreibweise.

Aber keine Ahnung, ob es etwas bringt. Wäre einfach mal ein Versuch wert. Ich selbst habe in Java noch nie gegen AD eine Anmeldung gemacht ...
 

Oneixee5

Top Contributor
meiner Meinung nach muss das so aussehen:
Java:
/**
  * Get Active Directory domain controllers.
  *
  * Shell example: nslookup -type=SRV _ldap._tcp.dc._msdcs.mydomain.local
  *
  * @param domain
  *            Domain name (e.g. "mydomain.local")
  * @return Domain controllers (list may be empty)
  * @throws NamingException
  */
 private static Collection<InetSocketAddress> getDomainControllers(String domain) throws NamingException {
     final String typeSRV = "SRV";
     final String[] types = new String[] { typeSRV };
     DirContext ctx = new InitialDirContext();
     Attributes attributes = ctx.getAttributes("dns:/_ldap._tcp.dc._msdcs." + domain, types);
     if (attributes.get(typeSRV) == null) {
         return Collections.emptyList();
     }
     NamingEnumeration<?> e = attributes.get(typeSRV).getAll();
     TreeMap<Integer, InetSocketAddress> result = new TreeMap<>();
     while (e.hasMoreElements()) {
         String line = (String) e.nextElement();
         // The line is: priority weight port host
         String[] parts = line.split("\\s+");
         int prio = Integer.parseInt(parts[0]);
         int port = Integer.parseInt(parts[2]);
         String host = parts[3];
         result.put(prio, new InetSocketAddress(host, port));
     }
     return result.values();
 }
Java:
LoginContext lc;
String domainName, username, password = ...
// get domain controller for login
Collection<InetSocketAddress> result = getDomainControllers(domainName);
if (result.isEmpty()) {
    throw new ValidationException("No domain controllers found for domain " + domainName);
}
String loginServer = result.iterator().next().getHostString();
System.setProperty("java.security.krb5.realm", domainName.toUpperCase());
System.setProperty("java.security.krb5.kdc", loginServer);

 // perform login
lc = new LoginContext("", null, new StaticCallbackHandler(username, password),
        new StaticConfiguration("com.sun.security.auth.module.Krb5LoginModule"));
lc.login();

// logout (we want to check the password only)
lc.logout();
domainName und username musst du einfach vorher splitten entweder per @ oder \ wie oben beschrieben
 

franzy

Aktives Mitglied
Guten Morgen,

ich hatte den Quelltext wie du ihn hier aufführst. Ich wollte ihn nur nicht komplett hier rein stellen, weil die getDomainControllers ja nur dazu da ist die Controller zu bekommen. In meinem Quelltext habe ich einen DC vorausgesetzt, daher meine Kürzungen.

Was meinst du mit:
domainName und username musst du einfach vorher splitten entweder per @ oder \ wie oben beschrieben

Das Problem ist nicht den Usernamen abzuschneiden. Nein an der Domaine wird sich so angemeldet, also muss ich doch auch hier den Usernamen so lassen.

Gibt es keine Möglichkeit die Domaine beim LoginContext mitzugeben oder eben anders?

Grüße Franzy
 

Oneixee5

Top Contributor
Bei mir funktioniert der Code so und es gibt hier im Landesnetz mehrere Domains. Allerdings beachte ich noch die Prioritäten, welche von der DNS-Anfrage zurückkommen, da es auch X DomainController gibt. Für die Anmeldung ist auch hier zwingend die Domain notwendig, sie ist aber niemals Teil des Usernamens sondern ein Feld im AD (OU=Domain Controllers,DC=*****,DC=de).
 

franzy

Aktives Mitglied
Hallo,

also mit dem @ geht auch nicht.

@Oneixee5: Du versteht etwas falsch. Ich habe doch oben einen Screen von einer Windows Anmeldung. Unter Windows kann man sich, wie in dem Screen gezeigt, mit der Domain und Benutzernamen anmelden. Das sollte an jedem Windows System gehen, wenn man vor den Namen die Domaine stellt, so zumindest die Aussage meines Netzwerkadmins. Und genau das will ich jetzt hier auch ermöglichen.
Ich verstehe dich wahrscheinlich noch nicht korrekt.

Grüße Franzy
 

franzy

Aktives Mitglied
Hallo zusammen,

durch den Hinweis von mihe7 habe ich gesehen wo mein Fehler lag, oder besser gesagt das Problem.
Ich erkläre vielleicht noch einmal was ich machen will.
Ich habe zwei Domainen und in beiden Domainen muss ich prüfen, ob der User vorhanden ist. Der kann nur in einem der Domainen vorhanden sein! Das stellt erst einmal so kein Problem dar. ein paar loops, fertig :), so habe ich gedacht.

Mein Problem jedoch kommt durch folgende Anweisung zustande:
Java:
System.setProperty("java.security.krb5.realm", domainName.toUpperCase());
System.setProperty("java.security.krb5.kdc", loginServer);

Wenn sich der Doaminname während der Verarbeitung ändert dann wird in der falschen Domaine gesucht. Das Property wird nicht überschrieben mit dem "neuen" Domainname, deshalb findet er den User auch nicht.

Erst wenn ich denn Applikationsserver neu restarte funktioniert es. Das ist aber Quatsch, ich muss ja während der Laufzeit prüfen.

Gibt es da eine andere Möglichkeit? Wie werden die denn im weiteren Verlauf verwendet? In der Klasse LoginContext finde ich kein getProperty in dem Kontext.

Grüße und danke an Alle!
 

Ähnliche Java Themen


Oben