[Rt-devel] SSO without ExternalAuth module

Mike Peachey mike.peachey at jennic.com
Sat Feb 27 07:11:07 EST 2010


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
http://www.jennic.com
__________________________________________________


More information about the Rt-devel mailing list