Hauptmenü

AD Verbindung

Begonnen von Timo, 07.10.2020 13:52:17

⏪ vorheriges - nächstes ⏩

Timo

Hallo zusammen,
ich möchte KIX mit dem AD verbinden. Jetzt habe ich hier schon die Anleitung gelesen:https://forum.kixdesk.com/index.php?topic=3487.0


Ich nehme an man meint über Putty mit SSH auf das Debian gehen und die folgende Datei bearbeiten: /opt/kix/Kernel/Config.pm[/size]
Leider finde ich unter dem genannten Pfad die Config.pm Datei nicht. Auch konnte ich über WinSCP keine Datei mit dem Namen finden, die ich für eine AD Verbindung bearbeiten könnte. Habe ich hier etwas grundlegend falsch verstanden? Wie gehe ich hier vor?[/size]

[/size]
Vielen Dank für eure Hilfe. [/size]

Torsten Thau

Hallo Timo,


die Konfiguration und Funktionalität in KIX18 differiert etwas von KIX17. Eine Anleitung zur Verwendung des AD zur Nutzerauthentifizierung findest Du hier:
https://docs.kixdesk.com/kix18Administration/kix-start/nutzerverwaltung/nutzer/verzeichnisdienste-nutzen


Hinweise zum Unterschied 17 vs- 18 findest Du hier:
https://forum.kixdesk.com/index.php?topic=5610.0


viele Grüße, Torsten


Timo

#2
Vielen Dank. Ich habe nun noch eine Frage:


Folgende Sachen verstehe ich nicht ganz, wie und ob ich was anpassen muss. Oberhalb das ganze Domänen OU gedönz habe ich abgeändert, aber hier bin ich mir teils nicht sicher. Ist da wirklich alles relevant? Die Ldap Sachen habe ich drüber angepasst nur die Stelle wo der Benutzername und Passwort gesetzt wird ist mir nicht ganz klar.


"Replace": "example_domain\\",
"ReplaceRegExp": "^(.+?)@.+?$"
"Name": "HTTPBasicAuth Example"
"Password": "radiussecret"
"Name": "Radius Example"
"ID": "id",
"Login": "login",
"Password": "password"
"DSN": "DBI:mysql:database=customerdb;host=customerdbhost",
"Password": "come_password",
"Table": "user",
"User": "some_user"


{
"Config": {
"Replace": "example_domain\\",
"ReplaceRegExp": "^(.+?)@.+?$"
},
"Enabled": 0,
"Module": "Kernel::System::Auth::HTTPBasicAuth",
"Name": "HTTPBasicAuth Example"
},
{
"Config": {
"Die": 0,
"Host": "radiushost",
"Password": "radiussecret"
},
"Enabled": 0,
"Module": "Kernel::System::Auth::Radius",
"Name": "Radius Example"
},
{
"Config": {
"Columns": {
"ID": "id",
"Login": "login",
"Password": "password"
},
"CryptType": "sha2",
"DSN": "DBI:mysql:database=customerdb;host=customerdbhost",
"Password": "come_password",
"Table": "user",
"Type": "mysql",
"User": "some_user"
},
"Enabled": 0,
"Module": "Kernel::System::Auth::DB",
"Name": "Foreign Database"
},


Torsten Thau

Hi Timo,


wenn Du nur ein AD anschließen willst kann das andere Gedöns weg - hier ein Beispiel für Auth mit Synchronisation gegen ein LDAP und Authentifizierung gegen die KIX-DB selbst.




{
  "Enabled": 1,                             #  !!! set valid if auth backend should be used !!!
  "Name": "LDAP Example",
  "Module": "Kernel::System::Auth::LDAP",
  "Config": {
    "Host": "ldap.example.com",
    "BaseDN": "dc=example,dc=com",
    "UID": "uid",
    "GroupDN": "cn=kixallow,ou=posixGroups,dc=example,dc=com",
    "AccessAttr": "memberUid",
    "UserAttr": "UID",
    "SearchUserDN": "cn=binduser,ou=users,dc=example,dc=com",
    "SearchUserPw": "some_password",
    "AlwaysFilter": "(&(mail=*)(objectclass=user)",
    "Charset": "utf-8",
    "Die": 1,
    "Params": {
      "port": 389,
      "timeout": 120,
      "async": 0,
      "version": 3
    }
  },
  "Sync": [
    {
      "Enabled": 1,                          # set valid if AuthSync should be used
      "Module": "Kernel::System::Auth::Sync::LDAP",
      "Config": {
        "GroupDNBasedRoleSync": {
          "SomeDN": {
            "Role1": 1,
            "Role2": 0,
            "Agent User": 1,                  # authorize Agent Portal use - step 1
            "Customer":   1,                  # authorize Self Service Portal Login - step 1          }
        },
        "AttributeBasedRoleSync": {
          "LDAPAttribute": {
            "some value": {
              "Role1": 1,
              "Role2": 0,
              "Agent User": 1,                # authorize Agent Portal use - step 1
              "Customer":   1,                # authorize Self Service Portal Login - step 1
            }
          }
        },
        "ContactUserSync": {
          "KIXAttribute":  "LDAPAttribute",
          "KIXAttribute2": "LDAPAttribute2",
          "KIXAttribute4": "SET:some value",
          "IsAgent":       "SET:1",           # authorize Agent Portal use - step 2
          "IsCustomer":    "SET:1"            # authorize Self Service Portal Login - step 2
        }
      }
    }
  ]
},

# other auth backends may follow here...
#{
#   # e.g. some other part of the LDAP-tree or some other LDAP-/AD...
#},

# do not forget the fallback auth backend - KIX own DB...
{
  "Config": {
    "CryptType": "sha2"
  },
  "Enabled": 1,
  "Module": "Kernel::System::Auth::DB",
  "Name": "Local Database"
}

# !!! remove any comments before copy-pasting - JSON does not know comments, but they're useful here !!!






viele Grüße, Torsten

Fritz-EDV

#4
Bei mir hapert es scheinbar an einem Filter


[Error][Kernel::System::Auth::LDAP::Auth][170] Search failed! Bad filter


Leider ist nicht wirklich schlüssig, welcher Filter genau problematisch ist.


[
  {
    "Config": {
      "AccessAttr": "memberUid",
      "AlwaysFilter": "(&(!objectClass=computer)(|(&(objectClass=organizationalPerson)(memberOf=CN=Serviceportal-Agent,OU=Sicherheitsgruppen,OU=Fritz-EDV,DC=fritz-edv,DC=local))(&(objectClass=organizationalUnit)(!objectClass=person))))",
      "BaseDN": "DC=Fritz-EDV,DC=local",
      "Charset": "utf-8",
      "Die": 1,
      "GroupDN": "CN=Serviceportal-Agent,OU=Sicherheitsgruppen,OU=Fritz-EDV,DC=fritz-edv,DC=local",
      "Host": "****",
      "Params": {
        "async": 0,
        "port": 389,
        "timeout": 120,
        "version": 3
      },
      "SearchUserDN": "CN=LDAP-Abgleich,CN=Users,DC=fritz-edv,DC=local",
      "SearchUserPw": "****",
      "UID": "sAMAccountName",
      "UserAttr": "",
      "UserSuffix": ""
    },
    "Enabled": 1,
    "Module": "Kernel::System::Auth::LDAP",
    "Name": "AD_Fritz-EDV",
    "Sync": [
      {
        "Config": {
          "AttributeBasedRoleSync": {
            "LDAPAttribute": {
              "some value": {
                "Role1": 1
              }
            }
          },
          "GroupDNBasedRoleSync": {
            "CN=Serviceportal-Agent,OU=Sicherheitsgruppen,OU=Fritz-EDV,DC=fritz-edv,DC=local": {
              "Ticket Agent": 1,
              "FAQ Editor": 1,
              "Asset Maintainer": 1,
              "Agent User": 1,
              "Customer Manager": 1
            }
          }
        },
        "Enabled": 1,
        "Module": "Kernel::System::Auth::Sync::LDAP"
      }
    ]
  },
  {
    "Config": {
      "Replace": "example_domain\\",
      "ReplaceRegExp": "^(.+?)@.+?$"
    },
    "Enabled": 0,
    "Module": "Kernel::System::Auth::HTTPBasicAuth",
    "Name": "HTTPBasicAuth Example"
  },
  {
    "Config": {
      "Die": 0,
      "Host": "radiushost",
      "Password": "radiussecret"
    },
    "Enabled": 0,
    "Module": "Kernel::System::Auth::Radius",
    "Name": "Radius Example"
  },
  {
    "Config": {
      "Columns": {
        "ID": "id",
        "Login": "login",
        "Password": "password"
      },
      "CryptType": "sha2",
      "DSN": "DBI:mysql:database=customerdb;host=customerdbhost",
      "Password": "come_password",
      "Table": "user",
      "Type": "mysql",
      "User": "some_user"
    },
    "Enabled": 0,
    "Module": "Kernel::System::Auth::DB",
    "Name": "Foreign Database"
  },
  {
    "Config": {
      "CryptType": "sha2"
    },
    "Enabled": 1,
    "Module": "Kernel::System::Auth::DB",
    "Name": "Local Database"
  }
]



Den Fehler gibts auch, wenn ich beim AlwaysFilter wieder den Standardwert "(!objectClass=computer)" eintrage

Torsten Thau

Moinsen Fritz,

AFAIK ist "(!objectclass=computer)" kein gültiger LDAP-Filter. Das muss eher so geschrieben werden: "(!(objectclass=computer))". In Deinem Beispiel schaut dass dann so (hier für bessere Lesbarkeit mit Zeilenumbruch, Zeile 2 und 10):


01: (&
02:  (!(objectClass=computer))
03:  (|
04:      (&
05:        (objectClass=organizationalPerson)
06:        (memberOf=CN=Serviceportal-Agent,OU=Sicherheitsgruppen,OU=Fritz-EDV,DC=fritz-edv,DC=local)
07:      )
08:      (&
09:        (objectClass=organizationalUnit)
10:        (!(objectClass=person))
11:      )
12:  )
13: )



CU, Torsten

Fritz-EDV

#6
Moin!

Danke, scheinbar war die Syntax tatsächlich falsch. Hatte den Filter eig. vorab im LDAP Browser getestet - ohne Probleme.

Jetzt gibts nen anderen Fehler beim GroupDNBasedRoleSync:


[Tue Oct 20 08:13:33 2020][Error][Kernel::System::User::RoleList][1258] Need UserID!
[Tue Oct 20 08:13:33 2020][Error][Kernel::System::Role::User::RoleUserAdd][55] Need AssignUserID!
[Tue Oct 20 08:13:33 2020][Error][Kernel::System::Role::User::RoleUserAdd][55] Need AssignUserID!
[Tue Oct 20 08:13:33 2020][Error][Kernel::System::Role::User::RoleUserAdd][55] Need AssignUserID!
[Tue Oct 20 08:13:33 2020][Error][Kernel::System::Role::User::RoleUserAdd][55] Need AssignUserID!
[Tue Oct 20 08:13:33 2020][Error][Kernel::System::Role::User::RoleUserAdd][55] Need AssignUserID!
[Tue Oct 20 08:13:33 2020][Error][Kernel::System::User::UserLookup][897] No UserID found for 'test'!
[Tue Oct 20 08:13:33 2020][Error][Kernel::System::User::UserLookup][897] No UserID found for 'test'!


Woher nehme ich die benötigte UserID und wie übergebe ich sie?

Fritz-EDV

#7
Scheinbar hatte ich wohl


"UserAttr":"UID"


versehentlich entfernt. Mit dem Parameter gibts keine Fehlermeldung mehr. Was der bewirkt, ist leider nicht dokumentiert - nach dem Lesen der LDAP.pm habe ich hier lediglich ein vage Vermutung. Funktionieren tut die LDAP Anbindung jedoch immer noch nicht nicht wie gewünscht und die ganze Docker Sache behindert mich mehr beim "Debugging" als das sie hilft.

[Tue Oct 20 14:02:21 2020][Notice][Kernel::System::Auth::LDAP::Auth] User: 'test' tried to authenticate with Pw: 'test' (REMOTE_ADDR: ::ffff:172.23.0.4)
[Tue Oct 20 14:02:21 2020][Notice][Kernel::System::Auth::LDAP::Auth] check for groupdn!
[Tue Oct 20 14:02:21 2020][Notice][Kernel::System::Auth::LDAP::Auth] User: test authentication failed, no LDAP group entry foundGroupDN='CN=Serviceportal-Agent,OU=Sicherheitsgruppen,OU=Fritz-EDV,DC=fritz-edv,DC=local', Filter='(member=test)'! (REMOTE_ADDR: ::ffff:172.23.0.4).
[Tue Oct 20 14:02:21 2020][Notice][Kernel::System::Auth::DB::Auth] User: test doesn't exist or is invalid!!! (REMOTE_ADDR: ::ffff:172.23.0.4)
[Tue Oct 20 14:02:21 2020][Error][Kernel::System::User::UserLookup][897] No UserID found for 'test'!


Zeilen 1-3 werden einem blöderweise nur angezeigt, wenn man das Debugging direkt im Pearl Modul aktiviert (Hardcoded!). Zeile 3 scheint mir aber eine wichtige Info zu sein, die man zum Fehler finden benötigt.

Torsten Thau

Hi,

was "UID" bedeutet, ist hier dokumentiert: https://docs.kixdesk.com/kix18Administration/kix-start/nutzerverwaltung/nutzer/verzeichnisdienste-nutzen ...jedoch vermisse ich in der Beschreibung einige Konfig.-optionen. Das werden wir nachtragen - ist in der nächsten Veröffentlichung drin.

Hier erstmal eine ergänzte Beispielkonfiguration mit (hoffentlich jetzt allen) Parametern, wie sie für ein AD aussehen könnten - auf Grund Zeitmangel Freihand geschrieben aus einer Tube Copy-Paste:


[
  {
    "Name": "Some Active Directory",
    "Enabled": 1,
    "Module": "Kernel::System::Auth::LDAP",
    "Config": {
      "AlwaysFilter": "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))",
      "BaseDN": "DC=intern,DC=CompanyX,DC=de",
      "Charset": "utf-8",
      "Die": 1,
      "Host": "ad1.intern.companyx.de",
      "Params": {
        "async": 0,
        "port": 389,
        "timeout": 10,
        "version": 3
      },

      "SearchUserDN": "CN=Ldap-User,OU=Systemkonten,DC=intern,DC=CompanyX,DC=de",
      "SearchUserPw": "password",

      "GroupDN": "CN=Helpdesk-Agenten,OU=Systemkonten,DC=intern,DC=CompanyX,DC=de",
      "AccessAttr": "member",
      "UID": "sAMAccountName",
      "UserAttr": "DN",

      "UserSuffix": ""
    },
    "Sync": [
      {
        "Config": {
          "ContactUserSync": {
            "Email": "mail",
            "Firstname": "givenName",
            "IsAgent": "SET:1",
            "IsCustomer": "SET:1",
            "Lastname": "sn",
            "UserLogin": "sAMAccountName"
          },
          "GroupDNBasedRoleSync": {
            "CN=Helpdesk-Agenten,OU=Systemkonten,DC=intern,DC=CompanyX,DC=de": {
              "Superuser": 1
            }
          }
        },
        "Enabled": 1,
        "Module": "Kernel::System::Auth::Sync::LDAP"
      }
    ]
  },

  {
    "Name": "Local Database",
    "Enabled": 1,
    "Module": "Kernel::System::Auth::DB",
    "Config": {
      "CryptType": "sha2"
    }
  }

]



Bei Deiner Konfiguration ist scheinbar auch etwas doppelt gemoppelt: Du gibst sowohl einen GroupDN als auch einen Filterung via Always-Filter an. Ich würde vorschlagen zunächst auf GroupDN zu verzichten, wenn Du weißt dass Dein permanenter Filter korrekt ist.

Deine aktuelle Konfiguration ist vermutlich weiterhin angepasst, da Dein Log auf "member" prüft (was bei einem AD so sein sollte, aber Deine Konfiguration (unten) noch AccessAttribute = "memberUid" setzt). Kannst Du den aktuellen Stand bereit stellen (Verbindungsdaten anonymisierten nicht vergessen)?

vG, T.


Fritz-EDV

#9
Guten Tag Torsten,

>> was "UID" bedeutet, ist hier dokumentiert
Stimmt, mein Fehler. Ich wollte mich dabei auch eigentlich auf das 'UserAttr' beziehen. Wobei der genaue Verwendungszweck des 'UID' in der Doku für meinen Geschmack auch noch ein wenig zu vage ist.

>> Ich würde vorschlagen zunächst auf GroupDN zu verzichten, wenn Du weißt dass Dein permanenter Filter korrekt ist.
Hatte das zum Zeitpunkt deiner Antwort schon soweit mit dem GroupDN zurechtgetüdelt, dass es wie gewünscht funktioniert.

Anbei mal meine gegenwärtige Config, Settings für Windows AD:
[
  {
    "Module": "Kernel::System::Auth::LDAP",
    "Name": "AD_Fritz-EDV",
    "Enabled": 1,
    "Config": {
           
      "Charset": "utf-8",
      "Die": 0, # -> Unklar; Soll Funktion wohl beenden wenn Verbindung zum LDAP Host nicht etabliert werden kann. Wenn =1 -> Funktion 'die' wird ausgelöst, wenn =0 wird statt dessen eine Meldung ins LOGFILE geschrieben
     
      "UID": "sAMAccountName",
     
      "GroupDN": "CN=Serviceportal-Agent,OU=Sicherheitsgruppen,OU=Fritz-EDV,DC=fritz-edv,DC=local", # Diese Gruppe wird nach Attributen durchsucht um die Mitgliedschaft zu verifizieren; Filter zum Durchsuchen wird zusammengesetzt aus 'AccessAttr' + 'UserAttr'
      "AccessAttr": "member", # Gibt das Attribut an, in welchem der zu verifizierende User aufzufinden ist. Attribut wird in der unter GroupDN genannten CN gesucht
      "UserAttr": "DN", # Unklar; wenn = 'DN' dann identifiziert Funktion den distinguishedName des Benutzers aus den Attributen (->Windows AD); Andere Werte werden als auszulesendes Attribut interpretiert; Wird zusammen mit 'AccessAttr' als Filter zur Bestätigung der Mitgliedschaft in 'GroupDN' verwendet
     
      "Host": "adgc.domain.tld",
      "Params": {
        "async": 0,
        "port": 389,
        "timeout": 120,
        "version": 3
      },
      "SearchUserDN": "CN=LDAP-Abgleich,CN=Users,DC=fritz-edv,DC=local",
      "SearchUserPw": "secret",
      "BaseDN": "DC=Fritz-EDV,DC=local",
      "AlwaysFilter": "(&(!(objectClass=computer))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(|(objectClass=organizationalPerson)(&(objectClass=organizationalUnit)(!(objectClass=person)))))"
    },
    "Sync": [
      {
        "Module": "Kernel::System::Auth::Sync::LDAP",
        "Enabled": 1,
        "Config": {
          "ContactUserSync": {
            "Email": "mail",
            "Firstname": "givenName",
            "IsAgent": "SET:1",
            "IsCustomer": "SET:1",
            "Lastname": "sn",
            "UserLogin": "sAMAccountName",
            "Phone": "telephoneNumber",
            "Fax": "facsimileTelephoneNumber",
            "Mobile": "mobile",
            "street": "streetAddress",
            "zip": "postalCode",
            "city": "l",
            "country": "co",
            "comments": "description" # <- dieses Funktioniert leider nicht :(
          },
          "GroupDNBasedRoleSync": {
            "CN=Serviceportal-Agent,OU=Sicherheitsgruppen,OU=Fritz-EDV,DC=fritz-edv,DC=local": {
              "Ticket Agent": 1,
              "FAQ Editor": 1,
              "Asset Maintainer": 1,
              "Agent User": 1,
              "Customer Manager": 1
            }
          }
        }
      }
    ]
  },
  {
    "Config": {
      "CryptType": "sha2"
    },
    "Enabled": 1,
    "Module": "Kernel::System::Auth::DB",
    "Name": "Local Database"
  }
]


Fragwürdig:
[Wed Oct 21 10:23:37 2020][Info][Kernel::System::Contact::ContactGet] No contact assigned to user id 3!
Bei neuen Benutzern wird kein Kontakt erstellt, wenn dieser keine eMail Adresse im AD hinterlegt hat. Ich würde hier statt einem erfolgreichen Login, eine Fehlermeldung erwarten. Frei nach dem Motto: "No eMail Address in AD found, contact your Admin"

Wenn ich das im Quelltext richtig lese, dann werden neue Kontakte automatisch der PrimaryOrganisationID 1 zugeordnet. Besser wäre es, wenn man die PrimaryOrganisationID aus den Attributen übergeben könnte. Könnte man im Sync {} Objekt unterbringen, da die LDAP Anbindung bei den meisten vermutlich pro Kunde angelegt wird. Somit müsste man dann vorab nur noch die Kunden im Kontaktverzeichnis anlegen. Die korrekte ID kann man ja dann aus der Datenbank entnehmen.

Weitere Anmerkungen:

"IsAgent": "SET:1"
"IsCustomer": "SET:1"


Diese Attribute sollten Konditional setzbar sein bei Mitgliedschaft in einer bestimmten Gruppe. Momentan müsste man für eine Unterscheidung zwischen Kunde und Agent eine separate AD Anbindung schaffen. Würde im Prinzip gut ins 'GroupDNBasedRoleSync' reinpassen.


Edit:

Bezüglich der Kundenzuordnung bin ich in Eigenregie mal das Kernel::System::Auth::Sync::LDAP Modul angegangen

Hinzugefügt in Zeile 48:
$Self->{OrganisationID}         = $Param{Config}->{OrganisationID} || '1';

Geändert in Zeile 242:
PrimaryOrganisationID => $Self->{OrganisationID},

Jetzt kann ich im Config Objekt einfach eine ID übergeben:

[
  {
    "Module": "Kernel::System::Auth::LDAP",
    "Name": "AD_Fritz-EDV",
    "Enabled": 1,
    "Config": {
           
      "Charset": "utf-8",
      "OrganisationID": "2",

[....]


Alle Kontakte werden dann automatisch bei der Anmeldung der ID zugeordnet. Ich muss vorher nur sicherstellen, dass der Kunde im RDBMS mit der entsprechenden ID bereits existiert.

Torsten Thau

Hey Fritz,


gute Tipps. Die nehme ich mal mit, das mit der Organisations-ID ist so einfach, dass es schon wieder genial ist :-). Das mit der Mailadresse ist tatsächlich durchgegangen, daraus mache ich mal einen Bug-Report.


Danke Dir & CU, Torsten

Fritz-EDV

Hallo Torsten,


Danke für die Blumen. :D Leider ist mir zu spät aufgefallen, dass ich meine Anpassungen im KIX Start nicht nutzen kann. Das SSP ist ja scheinbar ein Pro Feature - da habe ich jetzt wohl einige Stunden verbraten ohne einen Nutzen draus ziehen zu können :-/ Im Produktvergleichsdatenblatt ist ja beim SSP ein Haken gesetzt - weiter unten sieht man dann aber erst, dass das eigentliche SSP nicht wirklich mit inbegriffen ist. Da habe ich mich wohl in die Irre führen lassen. Das müsste mMn. auch nochmal überarbeitet werden.

Torsten Thau

Hi Fritz,


OK - Problem erkannt. Es gibt in Start das Webformular zum einstellen von Meldungen. Das ist eine Art "Kundenportal light". Dafür braucht es keine Authentifizierung - in der Doku ist es hier beschrieben: https://docs.kixdesk.com/kix18Administration/kix-start/kommunikation/webformular


Nochmals Danke - jetzt für diesen Hinweis.


PS: Die Authentifizierung bei fehlender Mailadresse sollte bereits eine Emailadresse für den Kontakt generieren. Das Team ist dran - warum das nicht fkt. hat.


CU, Torsten