LDAP + SingleSignOn ==> Panic! No UserData!!!

Hilfe zu Znuny Problemen aller Art
Locked
r00t
Znuny newbie
Posts: 6
Joined: 15 Nov 2007, 16:36

LDAP + SingleSignOn ==> Panic! No UserData!!!

Post by r00t »

Hallo,

auch ich kämpfe mit SingleSignOn in Verbindung mit LDAP und habe trotz intensiver Suche im Forum und auf Google keine Antworten zu meinen Fragen finden können.

Vorweg mal der aktuelle Stand:
OTRS authentifiziert Kundenbenutzer via LDAP gegen das AD des PDC, die Agenten hingegen liegen in der OTRS-DB.
Apache ist nun soweit konfiguriert dass er via NTLM (mod_auth_sspi) die Benutzerinfo der Kunden direkt bezieht, ohne dass diese nochmal eingegeben werden müssen.
Dazu hier die aktuelle Config.pm und apache2-httpd-new.include.conf sowie ein kleiner Auszug aus dem otrs.log:

Config.pm

Code: Select all

# --
# Kernel/Config.pm - Config file for OTRS kernel
# Copyright (C) 2001-2006 OTRS GmbH, http://otrs.org/
# --
# $Id: Config.pm.dist,v 1.18 2006/09/07 16:15:41 mh Exp $
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see http://www.gnu.org/licenses/gpl.txt.
# --
#  Note:
#
#  -->> OTRS does have a lot of config settings. For more settings
#       (Notifications, Ticket::ViewAccelerator, Ticket::NumberGenerator,
#       LDAP, PostMaster, Session, Preferences, ...) see
#       Kernel/Config/Defaults.pm and copy your wanted lines into "this"
#       config file. This file will not be changed on update!
#
# --

package Kernel::Config;

sub Load {
    my $Self = shift;
    # ---------------------------------------------------- #
    # ---------------------------------------------------- #
    #                                                      #
    #         Start of your own config options!!!          #
    #                                                      #
    # ---------------------------------------------------- #
    # ---------------------------------------------------- #

    # ---------------------------------------------------- #
    # database settings                                    #
    # ---------------------------------------------------- #
    # DatabaseHost
    # (The database host.)
    $Self->{'DatabaseHost'} = 'localhost';
    # Database
    # (The database name.)
    $Self->{'Database'} = 'otrs';
    # DatabaseUser
    # (The database user.)
    $Self->{'DatabaseUser'} = 'otrs';
    # DatabasePw
    # (The password of database user. You also can use bin/CryptPassword.pl
    # for crypted passwords.)
    $Self->{'DatabasePw'} = 'hot';
    # DatabaseDSN
    # (The database DSN for MySQL ==> more: "man DBD::mysql")
    $Self->{DatabaseDSN} = "DBI:mysql:database=$Self->{Database};host=$Self->{DatabaseHost};";

    # (The database DSN for PostgreSQL ==> more: "man DBD::Pg")
    # if you want to use a local socket connection
#    $Self->{DatabaseDSN} = "DBI:Pg:dbname=$Self->{Database};";
    # if you want to use a tcpip connection
#    $Self->{DatabaseDSN} = "DBI:Pg:dbname=$Self->{Database};host=$Self->{DatabaseHost};";

    # ---------------------------------------------------- #
    # fs root directory
    # ---------------------------------------------------- #
    $Self->{Home} = 'C:/OTRS/otrs';

    # ---------------------------------------------------- #
    # insert your own config settings "here"               #
    # config settings taken from Kernel/Config/Defaults.pm #
    # ---------------------------------------------------- #
    # $Self->{SessionUseCookie} = 0;
    # $Self->{'CheckMXRecord'} = 1;

    # ---------------------------------------------------- #

    # ---------------------------------------------------- #
    # data inserted by installer                           #
    # ---------------------------------------------------- #
    $Self->{'LogModule'} = 'Kernel::System::Log::File';
    $Self->{'LogModule::LogFile'} = 'C:/OTRS/otrs/var/log/otrs.log';
    # $DIBI$
    $Self->{'SystemID'} = 10;
    $Self->{'SecureMode'} = 1;
    $Self->{'Organization'} = '';
    $Self->{'FQDN'} = 'pdc.domain.local';
    $Self->{'DefaultLanguage'} = 'de';
    $Self->{'AdminEmail'} = 'edv@domain.local';
    $Self->{'DefaultCharset'} = 'utf-8';
    
    
    
    # ---------------- Entries by Rüdiger Bernhard --------------- #

		# ---------------------------------------------------- #
		# Entries for sending mail via a SMTP server           #
		# by Rüdiger Bernhard	2007-10-23											 #
		# ---------------------------------------------------- #
		
		# SendmailModule
		$Self->{"SendmailModule"} = "Kernel::System::Email::SMTP";
		$Self->{"SendmailModule::Host"} = "10.0.0.2";
		$Self->{"SendmailModule::AuthUser"} = "";
		$Self->{"SendmailModule::AuthPassword"} = "";

		# ---------------------------------------------------- #
		# Entries for authenticating customers via LDAP        #
		# by Rüdiger Bernhard	2007-11-12											 #
		# ---------------------------------------------------- #

    $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::LDAP';
    $Self->{'Customer::AuthModule::LDAP::Host'} = '10.0.0.1';
    $Self->{'Customer::AuthModule::LDAP::BaseDN'} = 'dc=domain,dc=local';
    $Self->{'Customer::AuthModule::LDAP::SearchUserDN'} = 'otrs_service@domain.local';
    $Self->{'Customer::AuthModule::LDAP::SearchUserPw'} = 'geheim';
    $Self->{'Customer::AuthModule::LDAP::UID'} = 'sAMAccountName';
    $Self->{'Customer::AuthModule::LDAP::UserAttr'} = 'DN';
    $Self->{'Customer::AuthModule::LDAP::GroupDN'} = 'dc=domain,dc=local';
    
    # customer Auth für Firma1
    $Self->{CustomerUser1} = {
    	  Name => 'LDAP Firma1',
        Module => 'Kernel::System::CustomerUser::LDAP',
        Params => {
        # ldap host
        Host => '10.0.0.1',
        # ldap base dn
        BaseDN => 'OU=Firma1,DC=domain,DC=local',
        GroupDN => 'dc=domain,dc=local',
        # search scope (one|sub)
        SSCOPE => 'sub',
        UserDN => 'otrs_service@domain.local',
        UserPw => 'geheim',
        AlwaysFilter => '(objectclass=user)',
        SourceCharset => 'utf-8',
				DestCharset => 'iso-8859-15',
    },
    # customer uniq id
    CustomerKey => 'sAMAccountName',
    # customer #
    CustomerID => 'mail',
    CustomerUserListFields => ['sAMAccountName', 'cn', 'mail'],
    CustomerUserSearchFields => ['sAMAccountName', 'cn', 'mail'],
    CustomerUserSearchPrefix => '',
    CustomerUserSearchSuffix => '*',
    CustomerUserSearchListLimit => 250,
    CustomerUserPostMasterSearchFields => ['mail'],
    CustomerUserNameFields => ['givenname', 'sn'],
    Map => [
        # note: Login, Email and CustomerID needed!
        # var, frontend, storage, shown, required, storage-type
        #[ 'UserSalutation', 'Title', 'title', 1, 0, 'var' ],
        [ 'UserFirstname', 'Firstname', 'givenname', 1, 1, 'var' ],
        [ 'UserLastname', 'Lastname', 'sn', 1, 1, 'var' ],
        [ 'UserLogin', 'Login', 'sAMAccountName', 1, 1, 'var' ],
        [ 'UserEmail', 'Email', 'mail', 1, 1, 'var' ],
        [ 'UserCustomerID', 'sAMAccountName', 'mail', 0, 1, 'var' ],
        [ 'UserPhone', 'Phone', 'telephonenumber', 1, 0, 'var' ],
        #[ 'UserAddress', 'Address', 'postaladdress', 1, 0, 'var' ],
        #[ 'UserComment', 'Comment', 'description', 1, 0, 'var' ],
        ],
    };
    
    # customer Auth für Firma2
    $Self->{CustomerUser2} = {
    	  Name => 'LDAP Firma2',
        Module => 'Kernel::System::CustomerUser::LDAP',
        Params => {
        # ldap host
        Host => '10.0.0.1',
        # ldap base dn
        BaseDN => 'ou=Firma2,dc=domain,dc=local',
        GroupDN => 'dc=domain,dc=local',
        # search scope (one|sub)
        SSCOPE => 'sub',
        UserDN => 'otrs_service@domain.local',
        UserPw => 'geheim',
        AlwaysFilter => '(objectclass=user)',
        SourceCharset => 'utf-8',
				DestCharset => 'iso-8859-15',
    },
    # customer uniq id
    CustomerKey => 'sAMAccountName',
    # customer #
    CustomerID => 'mail',
    CustomerUserListFields => ['sAMAccountName', 'cn', 'mail'],
    CustomerUserSearchFields => ['sAMAccountName', 'cn', 'mail'],
    CustomerUserSearchPrefix => '',
    CustomerUserSearchSuffix => '*',
    CustomerUserSearchListLimit => 250,
    CustomerUserPostMasterSearchFields => ['mail'],
    CustomerUserNameFields => ['givenname', 'sn'],
    Map => [
        # note: Login, Email and CustomerID needed!
        # var, frontend, storage, shown, required, storage-type
        #[ 'UserSalutation', 'Title', 'title', 1, 0, 'var' ],
        [ 'UserFirstname', 'Firstname', 'givenname', 1, 1, 'var' ],
        [ 'UserLastname', 'Lastname', 'sn', 1, 1, 'var' ],
        [ 'UserLogin', 'Login', 'sAMAccountName', 1, 1, 'var' ],
        [ 'UserEmail', 'Email', 'mail', 1, 1, 'var' ],
        [ 'UserCustomerID', 'sAMAccountName', 'mail', 0, 1, 'var' ],
        [ 'UserPhone', 'Phone', 'telephonenumber', 1, 0, 'var' ],
        #[ 'UserAddress', 'Address', 'postaladdress', 1, 0, 'var' ],
        #[ 'UserComment', 'Comment', 'description', 1, 0, 'var' ],
        ],
    };
    
    # customer Auth für Firma3
    $Self->{CustomerUser3} = {
    	  Name => 'LDAP Firma3',
        Module => 'Kernel::System::CustomerUser::LDAP',
        Params => {
        # ldap host
        Host => '10.0.0.1',
        # ldap base dn
        BaseDN => 'ou=Firma3,dc=domain,dc=local',
        GroupDN => 'dc=domain,dc=local',
        # search scope (one|sub)
        SSCOPE => 'sub',
        UserDN => 'otrs_service@domain.local',
        UserPw => 'geheim',
        AlwaysFilter => '(objectclass=user)',
        SourceCharset => 'utf-8',
				DestCharset => 'iso-8859-15',
				# CustomerGroupAlwaysGroups => 'users','zzv',
    },
    # customer uniq id
    CustomerKey => 'sAMAccountName',
    # customer #
    CustomerID => 'mail',
    CustomerUserListFields => ['sAMAccountName', 'cn', 'mail'],
    CustomerUserSearchFields => ['sAMAccountName', 'cn', 'mail'],
    CustomerUserSearchPrefix => '',
    CustomerUserSearchSuffix => '*',
    CustomerUserSearchListLimit => 250,
    CustomerUserPostMasterSearchFields => ['mail'],
    CustomerUserNameFields => ['givenname', 'sn'],
    Map => [
        # note: Login, Email and CustomerID needed!
        # var, frontend, storage, shown, required, storage-type
        #[ 'UserSalutation', 'Title', 'title', 1, 0, 'var' ],
        [ 'UserFirstname', 'Firstname', 'givenname', 1, 1, 'var' ],
        [ 'UserLastname', 'Lastname', 'sn', 1, 1, 'var' ],
        [ 'UserLogin', 'Login', 'sAMAccountName', 1, 1, 'var' ],
        [ 'UserEmail', 'Email', 'mail', 1, 1, 'var' ],
        [ 'UserCustomerID', 'sAMAccountName', 'mail', 0, 1, 'var' ],
        [ 'UserPhone', 'Phone', 'telephonenumber', 1, 0, 'var' ],
        #[ 'UserAddress', 'Address', 'postaladdress', 1, 0, 'var' ],
        #[ 'UserComment', 'Comment', 'description', 1, 0, 'var' ],
        ],
    };


		# ---------------------------------------------------- #
		# Entries for definition of worktime				           #
		# by Rüdiger Bernhard	2007-10-24											 #
		# ---------------------------------------------------- #

		$Self->{TimeWorkingHours} = {
			Mon => [ 9,10,11,12,13,14,15,16,17 ],
			Tue => [ 9,10,11,12,13,14,15,16,17 ],
			Wed => [ 9,10,11,12,13,14,15,16,17 ],
			Thu => [ 9,10,11,12,13,14,15,16,17 ],
			Fri => [ 9,10,11,12,13,14,15,16,17 ],
			Sat => [ ],
			Sun => [ ],
		};
		
		# ---------------------------------------------------- #
		# Entries for queue management							           #
		# by Rüdiger Bernhard	2007-12-05											 #
		# ---------------------------------------------------- #		
		
		# ticket acl
    $Self->{TicketAcl}->{'ACL-Name-1'} = {
        # match properties
        Properties => {
            # current ticket match properties
            Ticket => {
                Queue => ['Raw'],
            }
        },
        # return possible options (white list)
        Possible => {
            # possible ticket options (white list)
            Ticket => {
                State => ['new', 'open', 'pending reminder'],
            },
            # possible action options
            Action => {
                AgentTicketLock => 1,
                AgentTicketZoom => 1,
                AgentTicketClose => 0,
                AgentTicketPending => 1,
                AgentTicketNote => 1,
                AgentTicketHistory => 1,
                AgentTicketPriority => 1,
                AgentTicketFreeText => 1,
                AgentTicketHistory => 1,
                AgentTicketCompose => 1,
                AgentTicketBounce => 1,
                AgentTicketPrint => 1,
                AgentTicketForward => 1,
                AgentTicketPrint => 1,
                AgentTicketPhone => 1,
                AgentTicketPhoneOutbound => 1,
                AgentTicketCustomer => 1,
                AgentTicketMove => 1,
                AgentTicketOwner => 1,
                AgentTicketResponsible => 1,
                AgentLinkObject => 1,
            },
        },
    };


		# ---------------------------------------------------- #
		# Entries for single sign on								           #
		# by Rüdiger Bernhard	2008-04-03											 #
		# ---------------------------------------------------- #

    # This is an example configuration for an apache ($ENV{REMOTE_USER})
    # auth. backend. Use it if you want to have a singe login through
    # apache http-basic-auth
    $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::HTTPBasicAuth';

    # Note:
    # If you use this module, you should use the following
    # config settings as fallback, if user isn't login through
    # apache ($ENV{REMOTE_USER})
    # $Self->{CustomerPanelLoginURL} = 'http://host.example.com/not-authorised-for-otrs.html';
    # $Self->{CustomerPanelLogoutURL} = 'http://host.example.com/thanks-for-using-otrs.html';


    # ---------------------------------------------------- #
    # ---------------------------------------------------- #
    #                                                      #
    #           End of your own config options!!!          #
    #                                                      #
    # ---------------------------------------------------- #
    # ---------------------------------------------------- #
}

# ---------------------------------------------------- #
# needed system stuff (don't edit this)                #
# ---------------------------------------------------- #
use strict;
use vars qw(@ISA $VERSION);
use Kernel::Config::Defaults;
push (@ISA, 'Kernel::Config::Defaults');
$VERSION = '$Revision: 1.18 $';
$VERSION =~ s/^\$.*:\W(.*)\W.+?$/$1/;
# -----------------------------------------------------#

1;

apache2-httpd-new.include.conf

Code: Select all

# --
# added for OTRS (http://otrs.org/)
# $Id: apache2-httpd-new.include.conf,v 1.3 2007/04/16 12:11:53 martin Exp $
# --

# agent, admin and customer frontend
ScriptAlias /otrs/ "C:/OTRS/otrs/bin/cgi-bin/"
Alias /otrs-web/ "C:/OTRS/otrs/var/httpd/htdocs/"

<IfModule !mod_auth_sspi.c>
    LoadModule sspi_auth_module modules/mod_auth_sspi.so
</IfModule>

# if mod_perl is used
<IfModule mod_perl.c>

    # load all otrs modules
    Perlrequire C:/OTRS/otrs/scripts/apache2-perl-startup.pl

    # Apache::Reload - Reload Perl Modules when Changed on Disk
    PerlModule Apache2::Reload
    PerlInitHandler Apache2::Reload
    PerlModule Apache2::RequestRec

    # set mod_perl2 options
    <Location /otrs>
        # ErrorDocument 403 /otrs/customer.pl
        ErrorDocument 403 /otrs/index.pl
        SetHandler  perl-script
        PerlResponseHandler ModPerl::Registry
        Options +ExecCGI
        PerlOptions +ParseHeaders
        PerlOptions +SetupEnv
        Options +ExecCGI -Includes
        # AllowOverride None
        AuthName "-Testverzeichnis-"   
        AuthType SSPI
        SSPIAuth On
        SSPIAuthoritative On
        # SSPIDomain mediengruppe.local
        
        # SSPIOmitDomain on
        # SSPIOfferBasic on
        Require valid-user
    </Location>

</IfModule>

# directory settings
<Directory "C:/OTRS/otrs/bin/cgi-bin/">
    AllowOverride None
    Options +ExecCGI -Includes
    Order allow,deny
    Allow from all
    
        AuthName "Testverzeichnis"
        AuthType SSPI
        SSPIAuth On
        SSPIAuthoritative On
        # SSPIDomain mediengruppe.local
        
        # SSPIOmitDomain on
        # SSPIOfferBasic on
        Require valid-user
</Directory>
<Directory "C:/OTRS/otrs/var/httpd/htdocs/">
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

# MaxRequestsPerChild (so no apache child will be to big!)
MaxRequestsPerChild 400
otrs.log

Code: Select all

[Thu Apr 24 14:14:09 2008][Notice][Kernel::System::CustomerAuth::HTTPBasicAuth::Auth] User: DOMAIN\testuser authentification ok (REMOTE_ADDR: 10.40.0.17).
Jetzt zum Problem:
Wie man sieht, hätte ich in der Config.pm angegeben, dass OTRS die CustomerUser via HTTP Basic Authentication authentifizieren soll. Anhand der Einträge im otrs.log sieht man, dass OTRS die Benutzerinformationen vom Apache korrekt übergeben bekommt. Leider werden CustomerUser dennoch nicht angemeldet. Stattdessen erscheint die Kundenanmeldeseite mit der Meldung Panic! No UserData!!!.

Daher nun die Frage, warum die CustomerUser nicht angemeldet werden.
Kann / muss man die CustomerUser vielleicht in die lokale OTRS-DB syncen, damit SSO funktioniert?
Hätte schon nach einer Möglichkeit dafür gesucht, anscheinend gibt es für CustomerUser keine Funktion wie UserSyncLDAPMap, welche wie bei den Agenten die User von LDAP in die OTRS-DB synct.

Wie immer vielen Dank schon mal im Voraus an alle, die ein paar graue Zellen an dieses Problem verschwenden.

-Rüdiger
OTRS 2.2.6 auf
Windows 2K3 Server R2 32bit
schwabts
Znuny newbie
Posts: 12
Joined: 06 Feb 2008, 19:41

LDAP + SingleSignOn ==> Panic! No UserData!!!

Post by schwabts »

Hallo Rüdiger,
  • 1. evtl. könnte http://www.otrs-forum.de/viewtopic.php?f=16&t=2051 helfen. Als ich den Fehler hatte, habe ich gelesen, dass ein Sync nur bei Agenten gemacht wird:
    OTRS an Active Directory
    von jojo am 13 Feb 2008, 19:29

    wie ich schon schrieb:

    - Du brauchst nicht nur eine Kundenauthentifizierung sondern auch Kundendaten (CustomerUser)
    - Sync hat was mit Agenten zu tun, nichts mit Kunden
    Wenn Kunden also nicht in die OTRS-DB synchronisiert werden, aber trotzdem extern zu verwalten sind, muss man erreichen, dass an Stelle der OTRS-DB für die Kundenauthentifizierung eine andere Datenquelle, also das Active Directory, verwendet wird. Ich denke, dass Deine Config.pm das im Prinzip schon richtig macht; der Fehler "No UserData" deutet ja auch nicht darauf hin, dass die Kundendaten falsch wären, sondern dass sie gar nicht gefunden werden.
    2. Ich hatte mir zur Fehlersuche einen LDAP-Browser installiert und habe alle damit DNs, etc. nochmal überprüft.
    3. Für sehr aufschlussreich halte ich auch das im obigen Link angesprochene Projekt, ein eigenes Perl-Modul für ADS-Zugriffe entwickeln zu wollen.
Sorry, wenn sich alles etwas zu allgemein anhören sollte, aber das ist leider alles, was ich beitragen kann.

Grüsse, Thomas
maeck
Znuny newbie
Posts: 50
Joined: 10 Apr 2008, 13:25

LDAP + SingleSignOn ==> Panic! No UserData!!!

Post by maeck »

Hallo r00t,

ich habe gleiches Vorhaben, hast du schon eine Lösung dafür gefunden?

Würde mich über eine Rückmeldung freuen,
maeck
OTRS: 2.3.4
OS: Debian Linux
Apache2/MySQL 5
Locked