Friday, October 27, 2006

Here at Oxford we use WebAuth for web based Single Sign On (SSO) and when looking at tools we like to see how easily they can be WebAuth enabled. Thankfully Sakai makes it all pretty easy. Sakai has the ability to support two authentication methods at the same time so we can have a login route for both Oxford users (WebAuth) and for internal Sakai users.

Previously we have used the Apache WebAuth module but this time I decided to attempt to use the Java WebAuth Filter developed as part of the SIPE project here at Oxford. One note is that the Standford WebAuth download pages have a newer version of the Java WebAuth filter than the SIPE pages. The Java WebAuth implementation only works with Java 1.5.

The first thing is to configure Kerberos on the machine so that it points to the correct servers, on my Linux box at Oxford this means having a configuration file called /etc/krb5.conf containing:

[libdefaults]
default_realm = OX.AC.UK

[realms]
OX.AC.UK = {
kdc = kdc0.ox.ac.uk
kdc = kdc2.ox.ac.uk
kdc = kdc1.ox.ac.uk
admin_server = kdc-admin.ox.ac.uk
}

[domain_realm]
.ox.ac.uk = OX.AC.UK
ox.ac.uk = OX.AC.UK


I also needed the kerberos tools too, on Ubuntu these come as part of the krb5-user package (sudo apt-get install krb5-user). Once my machine was running with Kerboros I needed to visit the systems development team and get a kerberos principal, this involved saying hello to the nice people upstairs and then typing a password for my new principal (buckett/itss). This principal then had rights over my webauth principal (webauth/oucs-matthewb.oucs.ox.ac.uk) so that I could key a keytab for my webauth principal. I get a keytab with the commands:

buckett@oucs-matthewb:~ $ kadmin -p buckett/itss
Authenticating as principal buckett/itss with password.
Password for buckett/itss@OX.AC.UK:
kadmin: ktadd -k /home/buckett/.webauth.keytab webauth/oucs-matthewb.oucs.ox.ac.uk
Entry for principal webauth/oucs-matthewb.oucs.ox.ac.uk with kvno 4, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/home/buckett/.webauth.keytab.
Entry for principal webauth/oucs-matthewb.oucs.ox.ac.uk with kvno 4, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/home/buckett/.webauth.keytab.

This gives me a keytab file that allows the WebAuth filter to authenticate with the Kerberos server without having to ask me for a password every time I start it up. I also need to create a keyring file.

touch /home/buckett/.webauth.keyring

and set the permissions on both of the files to be as restrictive as possible (chmod 400 ~/.webauth.*).

The the sakai login tool needs to be changed to include the WebAuth filter.
This means dropping all the JARs from the WebAuth distribution (bcprov-jdk15-132.jar, commons-httpclient-3.0.jar, commons-logging-api-1.0.4.jar, commons-codec-1.3.jar, commons-logging-1.0.4.jar, webauth-java-1.2.jar) into the WEB-INF/lib folder.
The web.xml then needs some extra sections added (in bold).

  <description>Sakai 2 sample tools: login</description>

  <!-- Webauth Filter Start -->
  <filter>
   <filter-name>Webauth Filter</filter-name>
   <filter-class>uk.ac.ox.webauth.Filter</filter-class>
   <init-param>
     <param-name>WebAuthDebug</param-name>
     <param-value>true</param-value>
   </init-param>
   <init-param>
       <param-name>WebAuthServicePrincipal</param-name>
       <param-value>webauth/oucs-matthewb.oucs.ox.ac.uk</param-value>
   </init-param>
   <init-param>
       <param-name>WebAuthKeytab</param-name>
       <param-value>/home/buckett/.webauth.keytab</param-value>
   </init-param>
   <init-param>
       <param-name>WebAuthWebKdcPrincipal</param-name>
       <param-value>service/webkdc@OX.AC.UK</param-value>
   </init-param>
   <init-param>
       <param-name>WebAuthWebKdcURL</param-name>
       <param-value>https://webauth.ox.ac.uk:8443/webkdc-service/</param-value>
   </init-param>
   <init-param>
       <param-name>WebAuthLoginURL</param-name>
       <param-value>https://webauth.ox.ac.uk/login</param-value>
   </init-param>
   <init-param>
       <param-name>WebAuthKeyring</param-name>
       <param-value>/home/buckett/.webauth.keyring</param-value>
   </init-param>
   <init-param>
       <param-name>AutoAddKeys</param-name>
       <param-value>true</param-value>
   </init-param>
   <init-param>
       <param-name>AutoRemoveKeys</param-name>
       <param-value>true</param-value>
   </init-param>
   <init-param>
       <param-name>WebAuthExtraRedirect</param-name>
       <param-value>true</param-value>
   </init-param>
 </filter>
 <!-- Webauth filter end -->

   <filter>
       <filter-name>sakai.request</filter-name>
       <filter-class>org.sakaiproject.util.RequestFilter</filter-class>
   </filter>

   <filter>
       <filter-name>sakai.request.container</filter-name>
       <filter-class>org.sakaiproject.util.RequestFilter</filter-class>
      <init-param>
           <param-name>tool.placement</param-name>
           <param-value>true</param-value>
       </init-param>
       <init-param>
           <param-name>remote.user</param-name>
           <param-value>false</param-value>
       </init-param>
   </filter>

   <filter-mapping>
       <filter-name>sakai.request</filter-name>
       <servlet-name>sakai.login</servlet-name>
       <dispatcher>REQUEST</dispatcher>
       <dispatcher>FORWARD</dispatcher>
       <dispatcher>INCLUDE</dispatcher>
   </filter-mapping>

   <filter-mapping>
       <filter-name>sakai.request.container</filter-name>
       <servlet-name>sakai.login.container</servlet-name>
       <dispatcher>REQUEST</dispatcher>
   </filter-mapping>
 

   <!-- Webauth Filter Mapping Start -->
   <filter-mapping>
       <filter-name>Webauth Filter</filter-name>
       <servlet-name>sakai.login.container</servlet-name>
   </filter-mapping>
   <!-- Webauth Filter Mapping End -->

   <servlet>
       <servlet-name>sakai.login</servlet-name>
       <servlet-class>org.sakaiproject.login.tool.LoginTool</servlet-class>
       <init-param>
           <param-name>container</param-name>
           <param-value>/sakai-login-tool/container</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
   </servlet>


You will probably need to change the WebAuth filter configuration to point to the correct keyring/keytab files for you local installation.

The just edit your sakai.properties, making sure these are set.

# LOGIN/LOGOUT

# to include the user id and password for login on the gateway site
top.login=false

# to let the container handle login or not (set to true for single-signon type setups, false for just internal login)
container.login=true

xlogin.enabled=true
xlogin.text=Guests

Now if you startup Sakai it should provide you with two login buttons in the top right of the portal. One that uses WebAuth and one that uses the internal Sakai authentication.

No comments: