[solved] Customer SSO mit Linux Apache

Hilfe zu OTRS Problemen aller Art
Post Reply
meilon
Znuny newbie
Posts: 52
Joined: 28 Apr 2010, 15:16
Znuny Version: 5.0.18
Location: Leinfelden-Echterdingen

[solved] Customer SSO mit Linux Apache

Post by meilon »

Hallo!

Ich habe heute ITSM 2.0 installiert und wollte nun das bereits erfolgreich über unseren Windows 2003 AD laufende Customer Interface mit Singe Sign On ausstatten.

Habe dafür libapache2-mod-auth-kerb sowie msktutil inkl. Abhägigkeiten auf meinem Ubuntu Server 9.10 installiert, Kerberos eingerichtet sowie die Configs für Apache und OTRS angepasst. Jetzt bin ich soweit, dass mich der Browser nach keinem Kennwort mehr fragt, im OTRS SysLog eine erfolgreiche Authentifizierung vermerkt wird, aber anstatt des Customer Interfaces bekomme ich nur meine Loginseite für inkompatible Browser zu sehen.

Hier meine Configanpassungen:
/opt/otrs/Kernel/Config.pm

Code: Select all

# --
# Kernel/Config.pm - Config file for OTRS kernel
# Copyright (C) 2001-2009 xxx, http://otrs.org/
# --
# $Id: Config.pm.dist,v 1.21 2009/02/16 12:01:43 tr Exp $
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.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'} = 'xxx';
    # 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} = '/opt/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                           #
    # ---------------------------------------------------- #
    # $DIBI$
    $Self->{'SystemID'} = 10;
    $Self->{'SecureMode'} = 1;
    $Self->{'Organization'} = 'xxx';
    $Self->{'LogModule::LogFile'} = '/tmp/otrs.log';
    $Self->{'LogModule'} = 'Kernel::System::Log::SysLog';
    $Self->{'FQDN'} = '29otrs156.xxx.de';
    $Self->{'DefaultLanguage'} = 'de';
    $Self->{'AdminEmail'} = 'x@xxx.de';
    $Self->{'DefaultCharset'} = 'utf-8';

                # Ticket::Frontend::CustomerInfo*
    # (show customer user info on Compose (Phone and Email), Zoom and
    # Queue view)
    $Self->{'Ticket::Frontend::CustomerInfoCompose'} = 1;
    $Self->{'Ticket::Frontend::CustomerInfoZoom'} = 1;
    $Self->{'Ticket::Frontend::CustomerInfoQueue'} = 1;


                # ---------------------------------------------------- #
    # ---------------------------------------------------- #
    #                                                      #
    #           Customer LDAP & DB Data                    #
    #                                                      #
    # ---------------------------------------------------- #
    # ---------------------------------------------------- #

  # This is an example configuration for an LDAP auth. backend.
  # (take care that Net::LDAP is installed!)
  $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::LDAP';
  $Self->{'Customer::AuthModule::LDAP::Host'} = 'xxx.de';
  $Self->{'Customer::AuthModule::LDAP::BaseDN'} = 'ou=edv,dc=xxx,dc=de';
  $Self->{'Customer::AuthModule::LDAP::UID'} = 'sAMAccountName';
        $Self->{'AuthModule::LDAP::Charset'} = 'iso-8859-1';

  # The following is valid but would only be necessary if the
  # anonymous user do NOT have permission to read from the LDAP tree
  $Self->{'Customer::AuthModule::LDAP::SearchUserDN'} = 'cn=ldap,cn=users,dc=xxx,dc=de';
  $Self->{'Customer::AuthModule::LDAP::SearchUserPw'} = 'ldapuser';

  # CustomerUser
  # (customer user database backend and settings)
        $Self->{CustomerUser} = {
                Name => 'Datenbank',
                Module => 'Kernel::System::CustomerUser::DB',
                Params => { Table => 'customer_user',
                        # to use an external database
#           DSN => 'DBI:odbc:yourdsn',
#           DSN => 'DBI:mysql:database=customerdb;host=customerdbhost',
#           User => '', Password => '',
                },
                # customer uniq id
                CustomerKey => 'login',
                CustomerID => 'customer_id',
                CustomerValid => 'valid_id',
                CustomerUserListFields => ['first_name', 'last_name', 'email'],
#    CustomerUserListFields => ['login', 'first_name', 'last_name', 'customer_id', 'email'],
                CustomerUserSearchFields => ['login', 'last_name', 'customer_id'],
                CustomerUserSearchPrefix => '',
                CustomerUserSearchSuffix => '*',
                CustomerUserSearchListLimit => 250,
                CustomerUserPostMasterSearchFields => ['email'],
                CustomerUserNameFields => ['salutation', 'first_name', 'last_name'],
 #   ReadOnly => 1,
                Map => [
                        # note: Login, Email and CustomerID needed!
                        # var, frontend, storage, shown, required, storage-type, http-link
                        [ 'UserSalutation', 'Salutation', 'salutation', 1, 0, 'var' ],
                        [ 'UserFirstname', 'Firstname', 'first_name', 1, 1, 'var' ],
                        [ 'UserLastname', 'Lastname', 'last_name', 1, 1, 'var' ],
                        [ 'UserLogin', 'Login', 'login', 1, 1, 'var' ],
                        [ 'UserPassword', 'Password', 'pw', 0, 1, 'var' ],
                        [ 'UserEmail', 'Email', 'email', 0, 1, 'var' ],
                        [ 'UserCustomerID', 'CustomerID', 'customer_id', 0, 1, 'var' ],
                        [ 'UserComment', 'Comment', 'comments', 1, 0, 'var' ],
                        [ 'ValidID', 'Valid', 'valid_id', 0, 1, 'int' ],
                ],
        };

  # CustomerUser1
  # (customer user ldap backend and settings)
  $Self->{CustomerUser1} = {
                Name => 'LDAP',
    Module => 'Kernel::System::CustomerUser::LDAP',
    Params => {
      # ldap host
      Host => 'x.xxx.de',
      # ldap base dn
      BaseDN => 'dc=xxx,dc=de',
      # search scope (one|sub)
      SSCOPE => 'sub',
      # The following is valid but would only be necessary if the
      # anonymous user does NOT have permission to read from the LDAP tree
      UserDN => 'cn=ldap,cn=users,dc=xxx,dc=de',
      UserPw => 'ldapuser',
      AlwaysFilter => '(objectclass=user)',
      SourceCharset => 'utf-8',
      DestCharset => 'utf-8',
    },
    # customer uniq id
    CustomerKey => 'sAMAccountName',
    # customer #
    CustomerID => 'mail',
    CustomerUserListFields => ['cn', 'mail'],
    CustomerUserSearchFields => ['sAMAccountName', 'cn', 'mail', 'telephonenumber'],
    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', 'CustomerID', 'mail', 0, 1, 'var' ],
      [ 'UserPhone', 'Phone', 'telephonenumber', 1, 0, 'var' ],
      #[ 'UserAddress', 'Address', 'postaladdress', 1, 0, 'var' ],
      #[ 'UserComment', 'Comment', 'description', 1, 0, 'var' ],
    ],
  };

    # ---------------------------------------------------- #
    # ---------------------------------------------------- #
    #                                                      #
    #           Customer LDAP Auth                         #
    #                                                      #
    # ---------------------------------------------------- #
    # ---------------------------------------------------- #

    # This is an example configuration for an LDAP auth. backend.
    # (take care that Net::LDAP is installed!)
     $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::LDAP';
     $Self->{'Customer::AuthModule::LDAP::Host'} = 'xxx';
     $Self->{'Customer::AuthModule::LDAP::BaseDN'} = 'dc=xxx,dc=de';
     $Self->{'Customer::AuthModule::LDAP::UID'} = 'sAMAccountName';

    # Check if the user is allowed to auth in a posixGroup
    # (e. g. user needs to be in a group xyz to use otrs)
    #$Self->{'Customer::AuthModule::LDAP::GroupDN'} = 'cn=otrsallow,ou=posixGroups,dc=le-mail,dc=de';
    $Self->{'Customer::AuthModule::LDAP::AccessAttr'} = 'memberUid';
    # for ldap posixGroups objectclass (just uid)
#    $Self->{'Customer::AuthModule::LDAP::UserAttr'} = 'UID';
    # for non ldap posixGroups objectclass (full user dn)
    $Self->{'Customer::AuthModule::LDAP::UserAttr'} = 'DN';

    # The following is valid but would only be necessary if the
    # anonymous user do NOT have permission to read from the LDAP tree
    $Self->{'Customer::AuthModule::LDAP::SearchUserDN'} = 'cn=ldap,cn=users,dc=xxx,dc=de';
    $Self->{'Customer::AuthModule::LDAP::SearchUserPw'} = 'ldapuser';

    # in case you want to add always one filter to each ldap query, use
    # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
    $Self->{'Customer::AuthModule::LDAP::AlwaysFilter'} = '(objectclass=user)';

    # in case you want to add a suffix to each customer login name, then
    # you can use this option. e. g. user just want to use user but
    # in your ldap directory exists user@domain.
    #$Self->{'Customer::AuthModule::LDAP::UserSuffix'} = '@xxx.de';

    # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
    $Self->{'Customer::AuthModule::LDAP::Params'} = {
        port => 389,
        timeout => 120,
        async => 0,
        version => 3,
    };

    # ---------------------------------------------------- #
    # ---------------------------------------------------- #
    #                                                      #
    #           Agent LDAP Auth                            #
    #                                                      #
    # ---------------------------------------------------- #
    # ---------------------------------------------------- #


                # This is an example configuration for an LDAP auth. backend.
    # (take care that Net::LDAP is installed!)
    $Self->{'AuthModule'} = 'Kernel::System::Auth::LDAP';
    $Self->{'AuthModule::LDAP::Host'} = 'xxx.de';
    $Self->{'AuthModule::LDAP::BaseDN'} = 'dc=xxx,dc=de';
    $Self->{'AuthModule::LDAP::UID'} = 'sAMAccountName';

    # Check if the user is allowed to auth in a posixGroup
    # (e. g. user needs to be in a group xyz to use otrs)
    $Self->{'AuthModule::LDAP::GroupDN'} = 'cn=iuk,ou=edv,dc=xxx,dc=de';
    $Self->{'AuthModule::LDAP::AccessAttr'} = 'member';
    # for ldap posixGroups objectclass (just uid)
#    $Self->{'AuthModule::LDAP::UserAttr'} = 'UID';
    # for non ldap posixGroups objectclass (with full user dn)
    $Self->{'AuthModule::LDAP::UserAttr'} = 'DN';

    # The following is valid but would only be necessary if the
    # anonymous user do NOT have permission to read from the LDAP tree
    $Self->{'AuthModule::LDAP::SearchUserDN'} = 'cn=ldap,cn=users,dc=xxx,dc=de';
    $Self->{'AuthModule::LDAP::SearchUserPw'} = 'ldapuser';

    # in case you want to add always one filter to each ldap query, use
    # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
    $Self->{'AuthModule::LDAP::AlwaysFilter'} = '(objectclass=user)';

    # in case you want to add a suffix to each login name, then
    # you can use this option. e. g. user just want to use user but
    # in your ldap directory exists user@domain.
#    $Self->{'AuthModule::LDAP::UserSuffix'} = '@domain.com';

    # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
    $Self->{'AuthModule::LDAP::Params'} = {
        port => 389,
        timeout => 120,
        async => 0,
        version => 3,
    };

                # agent data sync against ldap
    $Self->{'AuthSyncModule'} = 'Kernel::System::Auth::Sync::LDAP';
    $Self->{'AuthSyncModule::LDAP::Host'} = 'ldap://x.xxx.de/';
    $Self->{'AuthSyncModule::LDAP::BaseDN'} = 'ou=edv,dc=xxx,dc=de';
    $Self->{'AuthSyncModule::LDAP::UID'} = 'sAMAccountName';
    $Self->{'AuthSyncModule::LDAP::SearchUserDN'} = 'cn=ldap,cn=users,dc=xxx,dc=de';
    $Self->{'AuthSyncModule::LDAP::SearchUserPw'} = 'ldapuser';
    $Self->{'AuthSyncModule::LDAP::UserSyncMap'} = {
        # DB -> LDAP
        UserFirstname => 'givenName',
        UserLastname  => 'sn',
        UserEmail     => 'mail',
    };

    # AuthSyncModule::LDAP::UserSyncInitialGroups
    # (sync following group with rw permission after initial create of first agent
    # login)
    $Self->{'AuthSyncModule::LDAP::UserSyncInitialGroups'} = [
        'users',
                                'admin',
                                'itsm-service',
                                'stats',
    ];

$Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::HTTPBasicAuth';
$Self->{CustomerPanelLoginURL} = 'http://x.xxx.de/login.html';
$Self->{CustomerPanelLogoutURL} = 'http://x.xxx.de/logout.html';


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

# ---------------------------------------------------- #
# needed system stuff (don't edit this)                #
# ---------------------------------------------------- #
use strict;
use warnings;

use vars qw(@ISA $VERSION);
use Kernel::Config::Defaults;
push (@ISA, 'Kernel::Config::Defaults');

use vars qw(@ISA $VERSION);
$VERSION = qw($Revision: 1.21 $)[1];

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

1;
Apache (nur das, was neu ist)

Code: Select all

<Location /otrs>
        AuthType Kerberos
        AuthName "Kerberos Login"
        KrbAuthRealms XXX.DE
        KrbServiceName HTTP
        Krb5Keytab /etc/krb5.keytab
        KrbMethodNegotiate on
        KrbMethodK5Passwd off
        require valid-user
</Location>
Im OTRS SysLog steht Apr 28 15:41:07 xxx OTRS-CGI-10[3224]: [Notice][Kernel::System::CustomerAuth::HTTPBasicAuth::Auth] User: username@XXX.DE Authentication ok (REMOTE_ADDR: x.x.x.x)., weitergeleitet werde ich aber auf meinen LoginURL mit einem weiteren "?Reason=SystemError" am Ende.

Hier noch der Ablauf im Apache access.log:

Code: Select all

x.x.x.x - - [28/Apr/2010:15:49:57 +0200] "GET /otrs/customer.pl HTTP/1.1" 401 656 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)"
x.x.x.x - username@XXX.DE [28/Apr/2010:15:49:57 +0200] "GET /otrs/customer.pl HTTP/1.1" 302 654 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)"
x.x.x.x - - [28/Apr/2010:15:49:57 +0200] "GET /otrs/customer.pl?Action=Login&RequestedURL= HTTP/1.1" 401 656 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)"
x.x.x.x - username@XXX.DE [28/Apr/2010:15:49:57 +0200] "GET /otrs/customer.pl?Action=Login&RequestedURL= HTTP/1.1" 302 810 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)"
x.x.x.x - - [28/Apr/2010:15:49:57 +0200] "GET /login.html?Reason=SystemError HTTP/1.1" 304 209 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)"
Was fehlt noch? Ich kann leider nirgends eine Fehlermeldung finden!

Grüße und Besten Dank
meilon
Last edited by meilon on 07 May 2010, 13:09, edited 1 time in total.
OTRS 5.0.18 :: ITSM auf Apache 2.4.18 (Ubuntu), Perl 5.22.1 mit Ubuntu Server 16.04.2
Agent Auth über ActiveDirectory, Customer Auth mit Kerberos SingleSignOn über ActiveDirectory
meilon
Znuny newbie
Posts: 52
Joined: 28 Apr 2010, 15:16
Znuny Version: 5.0.18
Location: Leinfelden-Echterdingen

Re: Customer SSO mit Linux Apache

Post by meilon »

Hat sich erledigt, ich bin von Kerberos auf NTLM umgestiegen. Da es dafür noch keine Anleitung im Wiki gab, habe ich mal eine erstellt.

Beste Grüße
meilon
OTRS 5.0.18 :: ITSM auf Apache 2.4.18 (Ubuntu), Perl 5.22.1 mit Ubuntu Server 16.04.2
Agent Auth über ActiveDirectory, Customer Auth mit Kerberos SingleSignOn über ActiveDirectory
jojo
Znuny guru
Posts: 15019
Joined: 26 Jan 2007, 14:50
Znuny Version: Git Master
Contact:

Re: [solved] Customer SSO mit Linux Apache

Post by jojo »

NTLM ist ziemlich outdated und buggy. Kerberos ist definitv der bessere Weg. Ich würde die Finger von NTLM lassen
"Production": OTRS™ 8, OTRS™ 7, STORM powered by OTRS
"Testing": ((OTRS Community Edition)) and git Master

Never change Defaults.pm! :: Blog
Professional Services:: http://www.otrs.com :: enjoy@otrs.com
meilon
Znuny newbie
Posts: 52
Joined: 28 Apr 2010, 15:16
Znuny Version: 5.0.18
Location: Leinfelden-Echterdingen

Re: [solved] Customer SSO mit Linux Apache

Post by meilon »

Problem ist aber, dass ich es nicht hinbekommen habe, einen Autologin hinzubekommen (sprich: Keine Benutzer und Kennworteingabe). NTLM ist eben viel einfacher und für den Firmeninternen Helpdesk vollkommen ausreichend.

Wenn du mir jetzt aber ein paar Punkte aufzeigen kannst, die mich überreden könnten, auf Kerberos umzusteigen, dann bitte gleich ein Dummy-Proof Tutorial für Windows Active Directory und Ubuntu Linux mit Apache 2 mitliefern, weil das zusammenbasteln aus mehreren Tutorials und Google Fehlersuchen hat bei mir offensichtlich nicht funktioniert.
OTRS 5.0.18 :: ITSM auf Apache 2.4.18 (Ubuntu), Perl 5.22.1 mit Ubuntu Server 16.04.2
Agent Auth über ActiveDirectory, Customer Auth mit Kerberos SingleSignOn über ActiveDirectory
Post Reply