SSO without ExternalAuth module

If one wanted to:

  1. set a cookie on another website (like
    RTSSO=a4ee5e021e26a2734727e6c4685e9584)
  2. have that other website insert some data into a database accessible by RT
    associating it with the cookie value of a4ee5e021e26a2734727e6c4685e9584)

… how would one have RT read that cookie and authenticate against the
database data from #2 in order to achieve a single sign on solution?

Ultimately we have users signed into a website throughout the day and want
them to be able to access RT without authenticating again. If they have not
accessed RT before they should be created. The database information should
contain their email address and username at a minimum to do this properly.

I’ve been through the ExternalAuth module a lot of times over the past two
days and I’m making no progress. I don’t understand what the fields are for
and how to set the cookies the module it needs. It seems that the
documentation on it is limited and there’s a note that says Cookie SSO
cannot be used for authentication. If anyone has any ideas or where to put
hooks to write my own code to do this within RT’s source please let me know.

I’m by no means an RT developer but I have a strong grasp of mysql, cookie
usage, and perl/php. I find RT difficult because of the way Mason loads
files mixed with HTML and perl. I’m not sure what files within RT would
handle this and I don’t want to break upgrades down the road.

Landon Stewart LStewart@SUPERB.NET
SuperbHosting.Net by Superb Internet Corp.
Toll Free (US/Canada): 888-354-6128 x 4199
Local and International: 206-438-5879 x 4199
Web hosting and more “Ahead of the Rest”: http://www.superbhosting.net

Landon Stewart wrote:

If one wanted to:

  1. set a cookie on another website (like
    RTSSO=a4ee5e021e26a2734727e6c4685e9584)
  2. have that other website insert some data into a database accessible
    by RT associating it with the cookie value
    of a4ee5e021e26a2734727e6c4685e9584)

… how would one have RT read that cookie and authenticate against the
database data from #2 in order to achieve a single sign on solution?

Ultimately we have users signed into a website throughout the day and
want them to be able to access RT without authenticating again. If they
have not accessed RT before they should be created. The database
information should contain their email address and username at a minimum
to do this properly.

This is exactly what CookieAuth was designed for. It was created for our
own website to integrate with RT in that way. The detail and
documentation has not been heavily worked on because there has been very
little interest in it. Nearly all ExternalAuth users seem to be using it
for LDAP authentication alone.

I’ve been through the ExternalAuth module a lot of times over the past
two days and I’m making no progress. I don’t understand what the fields
are for and how to set the cookies the module it needs. It seems that
the documentation on it is limited and there’s a note that says Cookie
SSO cannot be used for authentication. If anyone has any ideas or where
to put hooks to write my own code to do this within RT’s source please
let me know.

I’m by no means an RT developer but I have a strong grasp of mysql,
cookie usage, and perl/php. I find RT difficult because of the way
Mason loads files mixed with HTML and perl. I’m not sure what files
within RT would handle this and I don’t want to break upgrades down the
road.

RT is certainly not an easy application to get to grips with. It takes
time and a decent amount of understanding of how Mason works.

Let me provide you with a few basics on Cookie Auth, then if you can be
specific with respect to your difficulties, I may be able to point you
in the right direction.

For CookieAuth to work, RT needs three things: its internal database, an
external database with external users in it, and a table that stores
cookies for those users to match against browser cookies.

Here’s an example for such a setup:

This defines the authentication services:

Set($ExternalAuthPriority, [‘WebsiteCookie’, ‘WebsiteMySQL’]);

This defines the information services, such as whether a user is

disabled and what their name is (cannot be stored in cookies)
Set($ExternalInfoPriority, [‘WebsiteMySQL’]);

Do not create users unless they’re in the website’s database

Set($AutoCreateNonExternalUsers, 0);

External settings contains all of the MySQL/Cookie details

Set($ExternalSettings, {

This details the website’s own database that already handles your

website users
‘WebsiteMySQL’ => { ‘type’ => ‘db’,

enable it for authentication and information

                                                     'auth' 
          =>  1,
                                                     'info' 
          =>  1,
                                                     'server' 
          =>  'localhost',
                                                     'database' 
          =>  'website_main',
                                                     'table' 
          =>  'website_users',

The user to connect to the database as

                                                     'user' 
          =>  'MYSQL_USER',
                                                     'pass' 
          =>  'MYSQL_PASS',
                                                     'port' 
          =>  '3306',

The perl DBI driver to use for the connection

                                                     'dbi_driver' 
          =>  'mysql',

The field in the users table that stores the username

                                                     'u_field' 
          =>  'username',

The field that holds the users’ passwords

                                                     'p_field' 
          =>  'password',

Since passwords are almost never stored in plain text, in order to

test passwords we’re going to need to make a hash using an encryption
algorithm from perl in order to compare the hashes. Since it’s perl we
need to know what perl package and subroutine to use so we can load them:

The perl encryption package that is needed to test the password

                                                     'p_enc_pkg' 
          =>  'Crypt::MySQL',

The function from the encryption package to use

                                                     'p_enc_sub' 
          =>  'password',

This one is slightly confusing, but it was to satisfy some poor design

in our externally developed website database. Basically a user is
considered disabled if there is a database field containing a specific
value. So, it could be a field called “disabled” with values of 0 or 1
in which case d_field would be “disabled” and d_values" would just be
“1” where 1 means the user is disabled. It could also be used so that if
the field contains any of an array of different possible values then the
user should be considered disabled.
‘d_field’
=> ‘disabled’,
‘d_values’
=> [‘1’],

The attr_match_list and attr_map are documented as well as I can

document them in the example config file that ships.

‘attr_match_list’ => [ ‘Gecos’,

                  'Name'

              ],
                                                     'attr_map' 
          =>  {   'Name' => 'username',

                  'EmailAddress' => 'email',

                  'ExternalAuthId' => 'username',

                  'Gecos' => 'userID'

              }
                                                 },

The MySQL details above would allow you to JUST authenticate users

against the website database, the Cookie section below is what allows
you to define cookies that the website sets to auth logins.

‘WebsiteCookie’ => { ‘type’ => ‘cookie’,

The name of the cookie as taken from the browser:

                                                     'name' 
          =>  'CustomCookie',

The table in the database that stores users

                                                     'u_table' 
          =>  'website_users',

The field in the users table that stores usernames

                                                     'u_field' 
          =>  'username',

The field in the users table that is a foreign key in the cookies

table. You would probably want to specify the primary key i.e. the users
unique ID which would be the primary key for the users table and a
primary and foreign key in the cookies table. If you store the cookies
in the users table itself then you need to fudge this so that the u_ and
c_ options all match up to point to the same table, but this is set up
for the cookies being stored in an alternate table and as such allows
there to more than one cookie per user.
‘u_match_key’
=> ‘userID’,

So this is that table that store the username/cookie combinations

                                                     'c_table' 
          =>  'website_logins',

The field that contains the cookie itself (in this case named the same

as the browser cookie is
‘c_field’
=> ‘CustomCookie’,

The field in the cookie table that refers to users in the user table

as defined above, effectively a foreign key.
‘c_match_key’
=> ‘loginUserID’,

The RT “ExternalSettings” database provider to tie these cookie

settings to (ie. the MySQL service defined above)

         'db_service_name'           =>  'WebsiteMySQL'
                                                 }
                         }

);

Hopefully that clears it up a little. As I said, if you come back with
specific issues I can try to clean it up for you.

This really ought to live in RT-Users instead of RT-Devel and I have
CC’d that list. I think you ought to respond to that list instead.
Kind Regards,

Mike Peachey, IT
Tel: +44 114 281 2655
Fax: +44 114 281 2951
Jennic Ltd, Furnival Street, Sheffield, S1 4QT, UK
Comp Reg No: 3191371 - Registered In England