RT with external auth (was Re: HTTP_Auth with rt?)

Hello,

I found a way for RT to use an external source for initial
authentication, and still use cookies for subsequent authentication.

First, some history :

i thought i read something on the list that suggested you could
have rt do authentication via http auth, but I can’t find any
documentation on how to do that.

– snip –

From rt/etc/config.pm:

WEB_AUTH_MECHANISM defines what sort of authentication you’d like to use

for the web ui. Valid choices are: “cookies” and “external”. Cookies

– snip –

I use mod_auth_pam with this, which is a drop-in replacement for mod_auth,
but which uses PAM instead of just /etc/passwd. The advantage is that I
can use our distributed authentication system (kerberos, via pam_krb5
etc). The disadvantage is that I have no good way of expiring logins,
like one would if one were using cookies. Because HTTP doesn’t support

– snip –

My wishlist for RT would include the ability to do initial authentication
via external auth mechanisms, but to have RT generate and track
authentication cookies to enable session expiry/logouts.

Here’s how I accomplished Joe’s wish (i.e. initial auth via external
mechanism, subsequent “session” auth via cookies) :

Two easy steps :

1)
    in lib/rt/database/config.pm, added a f() to do external
authentication.  Parameters are username and password that were
entered by the user when they filled out the login form.  If the
external authentication succeeds, then the password is stored in
RT's "users" database for the indicated username.

    In my case, my external auth source is a WinNT domain
controller.  Hence, I use the perl Authen::Smb module.  Here's the
actual code:

    # if the user's submitted password is his MSOE NT domain password, then
    # update the rt db to have his nt password
    sub msoe_authenticate {
        my ($username, $password) = @_;
        my ($user_id, $pass) = ($dbh->quote("$username"),
        $dbh->quote("$password"));
             
        use Authen::Smb;
        my $authResult = Authen::Smb::authen($username,
                     $password, 'yamato', 'hood', 'MSOE');
        if ( $authResult == Authen::Smb::NO_ERROR ) {
            # user submitted a valid password.  Let's put it into RT
            my $sql = qq[UPDATE users SET password = $pass WHERE user_id = $user_id];
            $dbh->Query($sql) or
                    warn "[msoe_authenticate] Sql had some problems: $Mysql::db_errstr\n$sql";
        }
    }

2)
in lib/rt/ui/web/auth.pm, modify AuthCheck() like so:

after the cookies are created and sent to the browser, insert a call
to my organization's authentication f() that I described in point 1)
above.  That's it.  The return value of my f() is irrelevant.

Essentially what this does is this: enables RT to use its stock auth
procedure against the external auth-source password, by ensuring that the
value for the password field in the users table is the external
auth-source password.
Happy Landings,

Jon Detert
Unix System Administrator, Milwaukee School of Engineering
1025 N. Broadway, Milwaukee, Wisconsin 53202

    # if the user's submitted password is his MSOE NT domain 

password, then
# update the rt db to have his nt password
sub msoe_authenticate {
my ($username, $password) = @_;
my ($user_id, $pass) = ($dbh->quote(“$username”),
$dbh->quote(“$password”));

        use Authen::Smb;
        my $authResult = Authen::Smb::authen($username,
                     $password, 'yamato', 'hood', 'MSOE');
        if ( $authResult == Authen::Smb::NO_ERROR ) {
            # user submitted a valid password.  Let's put it into RT
            my $sql = qq[UPDATE users SET password = $pass WHERE 

user_id = $user_id];
$dbh->Query($sql) or
warn “[msoe_authenticate] Sql had some
problems: $Mysql::db_errstr\n$sql”;
}
}

Hmm. Doesn’t this stick the users password into the DB in cleartext?

Seems like you might do better to add a one-time password into the
mix. You could essentially call your msoe_authenticate() function
passing in the one-time password. If the MSOE authentication
succeeds, the onetime password could get stored in the database (in
place of the domain password).

Still, a very nifty hack/patch!

— Eric

Date: Wed, 14 Feb 2001 13:54:47 -0800
From: Eric Goodman ericg@cats.ucsc.edu
To: rt-users@fsck.com
Subject: Re: RT with external auth (was Re: [rt-users] HTTP_Auth with rt?)

    # if the user's submitted password is his MSOE NT domain 

password, then
# update the rt db to have his nt password
sub msoe_authenticate {
my ($username, $password) = @_;
my ($user_id, $pass) = ($dbh->quote(“$username”),
$dbh->quote(“$password”));

        use Authen::Smb;
        my $authResult = Authen::Smb::authen($username,
                     $password, 'yamato', 'hood', 'MSOE');
        if ( $authResult == Authen::Smb::NO_ERROR ) {
            # user submitted a valid password.  Let's put it into RT
            my $sql = qq[UPDATE users SET password = $pass WHERE 

user_id = $user_id];
$dbh->Query($sql) or
warn “[msoe_authenticate] Sql had some
problems: $Mysql::db_errstr\n$sql”;
}
}

Hmm. Doesn’t this stick the users password into the DB in cleartext?

Seems like you might do better to add a one-time password into the
mix. You could essentially call your msoe_authenticate() function
passing in the one-time password. If the MSOE authentication
succeeds, the onetime password could get stored in the database (in
place of the domain password).

Still, a very nifty hack/patch!

yes, pretty nifty. That helps me fill out what I might try if I ever get
my head around Authen::Krb5-1.2, which is what I’ll use in place of the
recent mod_auth_pam that’s been giving me trouble in RedHat 7.0/Mandrake
7.2 environments. Would have the advantage of being more portable too,
since Apache+Perl is more widely available than Apache+PAM+Perl.

I’d probably want to at least work off of some kind of one-way hash of the
passwords themselves, rather than use them unencrypted. But, I don’t have
any working code, either now, do I? :wink:

–Joe