Project index

Adapting Sakai Authentication and Authorization

The SakaiVre project aims to use Shibboleth for authentication of users to Sakai, and provision of attributes upon which Sakai access control decisions can be based. This page contains some notes about how we might be able to achieve this.

Note: This page is somewhat misnamed, since we now learn that it is the Sakai GroupProvider interface that handles requests for role information used for access control.

Contents:

1. Sakai UserDirectoryProvider

Sakai looks to an implementation of UserDirectoryProvider (file /user/user-api/api/src/java/org/sakaiproject/user/api/UserDirectoryProvider.java) to provide authentication information, and access to some basic information (email, firstname, etc.) for a user (see /user/user-api/api/src/java/org/sakaiproject/user/api/UserEdit.java).

This seems to be a logical place to hook in to a Shibboleth infrastructure.

From [1] (slide 25):

Also slide 33:

User role is similar to, but not the same as a user type. I think type is scoped to a site or system, but role is particular to an administrative domain. Also, type is fixed at login, but roles may change dynamically during a session in response to external administrative changtes. Ultimately, access decisions are based on role membership. Access to role and principal information is provided by an instantiation of the GroupProvider interface (see /authz/authz-api/api/src/java/org/sakaiproject/authz/api/GroupProvider.java).

2. Digging in the code

The javadocs for the UserDirectoryProvider interface can be found at http://source.sakaiproject.org/release/2.1.2/javadoc/org/sakaiproject/service/legacy/user/UserDirectoryProvider.html and interface itself is defined here

}}}

Unfortunately, documentation about how to add a new authentication scheme seems to be rather sparse, apart from the javadocs [2], but the source tree contains some sample code and occasional hints:

/sakai-src/providers/README.txt /sakai-src/providers/component/src/webapp/WEB-INF/components.xml /sakai-src/providers/component/project.xml /sakai-src/providers/jldap/src/java/edu/amc/sakai/user/JLDAPDirectoryProvider.java /sakai-src/providers/jldap/README_JLDAP.txt }}}

There is a bit more documentation associated with the Kerberos provider:

/sakai-src/providers/kerberos/src/java/org/sakaiproject/component/kerberos/user/KerberosUserDirectoryProvider.java }}}

Examination of the interface for UserDirectoryProvider seems to indicate that the authentication interface is always used with a supplied user id. But with Shibboleth, the User id is determined in the web request processing path, and provided in the HTTP request headers, so we need to figure a way to get Sakai to use the supplied value rather than prompt for a new username.

Someone else seems to have trod this path: http://tp.its.yale.edu/pipermail/cas/2004-November/000882.html:

This is pretty much what I was hoping to do (cf. SakaiVre/ShibbolethWebAuthIntegration#Levels) But this doesn't say how to actually establish the user session based on the SSO credentials. There's more: http://tp.its.yale.edu/pipermail/cas/2004-December/000889.html. The key steps seem to be:

  1. edit sakai.properties:
    • {{{top.login = false

container.auth = true }}}

  1. optionally edit webapps/sakai-chef-tool/vm/sitenav/login.vm, change "Login" text to "Login through CAS", and add a link to login without CAS.
    • {{{<input type="button" class="button" value="Login through CAS" onclick="parent.location='$login_url'" />

<input type="button" class="button" value="Login without CAS" onclick="parent.location='/login'" /> }}}

But this leaves a remaining question about how similar CAS is to Shibboleth in the way that it supplies credentials. Looking at https://content.cc.vt.edu/confluence/display/DEV/Sakai+Installation+Notes, it appears that container.auth = true or container.login = false is key here. So maybe I just need to check out sakai.properties, following http://cvs.sakaiproject.org/release/2.0.1/SourceInstallGuide.html#Configuration.

Check out /sakai-src/docs/sakai.properties;

# (set to true for single-signon type setups, false for just internal login) container.login = false }}} Not a lot of help there, then. But there is also a document docs/architecture/sakai_properties.doc, but that doesn't really add any useful information.

So how do we get the container login details to the UserDirectoryProvider module?

The page at http://bug.sakaiproject.org/confluence/display/ENTR/CASifying+Sakai suggests that if Tomcat is being fed via Apache and the JK filter module, then the necessary authentication details established by the chosen authentication module in Apache HTTPD (which is how our Shibboleth deployment is set up) are passed automatically to the servlet container and will hence be picked up by Sakai. Does this mean that Sakai will not call the UserDirectoryProvider module, or will it still attempt to obtain attributes that way? I think we'll want to map the user type (e.g. see oucsStatus in SakaiVre/AttributeMappingsTable) to something that can be used across our federation to query or test for role membership.

3. Simple authentication

Based on the message at http://tp.its.yale.edu/pipermail/cas/2004-December/000889.html, and documentation at http://bugs.sakaiproject.org/confluence/display/ENTR/CASifying+Sakai, we tried to create a very simple authentication(-only) scheme for Sakai using Shibboleth. That is, allowing a Shibboleth authentication to be accepted in place of Sakai's default interactive username/password login.

What we did:

  1. The Apache HTTPD, Tomcat and JK connector have already been installed and configured (see TomcatNotes).

  2. Arrange to access Sakai via Apache HTTPD and the JK connector. File /etc/httpd/conf.d/jk.conf was edited to contain:

JkMount /portal/* ajp13w JkMount /library/* ajp13w JkMount /sakai-login ajp13w JkMount /sakai-login/* ajp13w }}}

  1. Test that the Sakai portal can now be accessed using the standard HTTP port (as opposed to the Tomcat port 808 - at this stage, access via port 8080 is also possible.)
  2. Apply Shibboleth access control via the Shibboleth SP configuration file (default /etc/httpd/conf.d/shib.conf, but we use /etc/httpd/conf.d/shib-sp.conf:

    • {{{<location /sakai-login>

</Location> }}}

  1. Confirm that Tomcat authentication is disabled for requests incoming on the JK connector - this allows tomcat to use Authentication details provided by authentication modules in the Apache HTTPD server. File $CATALINA_HOME/conf/server.xml:

    • {{{<!-- Define an AJP 1.3 Connector on port 8009 -->

<Connector port="8009"

}}}

  1. Tell Sakai to use servlet container authentication information. Create file $CATALINA_HOME/sakai/sakai.properties, containing the following:

    • {{{# 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) # (different documents give container.login or container.auth, so both are included here.) container.login = true container.auth = true }}}

  1. Login to Sakai as user admin (default password 'admin'), and create a new user corresponding to the Shibboleth login that will be used. If this step is omitted, Sakai will ignore the Shibboleth-authenticated user and force an interactive login (at URI path '/portal/relogin').

3.1. Configure persistent user database

By default, Sakai uses an in-memory hypersonic database for its user listings, which is re-initialized each time Sakai is restarted. To configure a persistent database using Hypersonic, edit $CATALINA_HOME/sakai/sakai.properties thus:

# second for disk based #url@javax.sql.BaseDataSource=jdbc:hsqldb:. url@javax.sql.BaseDataSource=jdbc:hsqldb:${sakai.home}/db/sakai.db }}}

3.2. Getting the OUCS username into a SAML assertion

To simply release the OUCS primary usert name, edit file /opt/shiiboleth-idp/etc/resolver.ldap.xml, adding an entry of the form:

</SimpleAttributeDefinition> }}}

But this isn't enough to get the username recognized as container authentication username. By default, Shibboleth uses attribute eduPersonPrincipalName to identify the user, so use this instead: {{{<SimpleAttributeDefinition id="urn:mace:dir:attribute-def:eduPersonPrincipalName"

</SimpleAttributeDefinition> }}}

In https://authdev.it.ohio-state.edu/twiki/bin/view/Shibboleth/IdPAttributeConfig, we see:

and under the description of <SimpleAttributeDefinition id="URN">:

3.3. Using a Shibboleth attribute to signal container authentication

The example at https://authdev.it.ohio-state.edu/twiki/bin/view/Shibboleth/AttributeAcceptancePolicy contains this:

</AttributeRule> }}}

In our /etc/shibbboleth/AAP.xml config file, we have placed the following definition:

</AttributeRule> }}}

(Note that we are not using attribute scoping here, which may be a security hole.)

To test this, we Shibboleth-protected the standard Tomcat JSP example pages by adding the following to /etc/httpd/conf.d/shib-sp.conf:

</Location> }}} and then browse to http://sakai-vre-demo.oucs.ox.ac.uk/jsp-examples/snp/snoop.jsp, which displays a page of request information, including the requesting username, generated by this JSP: <%= request.getRemoteUser() %>.

3.4. Linking to servlet authentication

In order to get Shib-EP-Principalname passed to Tomcat, uncomment the following in AAP.xml (and edit the "Header=" attribute if necessary):

</AttributeRule> }}}

The refers to application context parameters or servlet init parameters that may be defined in the application's web.xml configuration file. This example comes from the SPIE test servlet configuration:

Here, parameter 'attributeAsUsername' indicates Shibboleth attributes that are mapped to JAAS principals, and 'attributeAsRoles' indicates an attribute that conveys roles that have been assigned to the authenticated user.

4. Using Shibboleth Attributes for access control

Prompted by some questions about how we might use the SPIE JAAS module to pass Shibboleth attributes into Sakai, there has been some lively discussion on the sakai-dev mailing list, and many details have become clearer. In particular, it seems that the Sakai authorization structure is a poor fit with Shibboleth attribute delivery. Alistair Young has encountered similar issues with his Guanxi development, and is taking the approach of constructing a "pod" of data from Shibboleth assertions, suitable for responding to Sakai authorization queries.

The discussion of Shibboleth integration with Sakai on the sakai-dev mailing list occurs about the end of July 2006 and start of August 2006. Key messages have been copied to our internal mailing list and can be reviewed here:

There are also some comments from Steven Carmody of the Internet2 Shibboleth project, and my response:

This discussion has clarified the scope for interaction between Sakai authentication, Sakai authorization and Shibboleth. Unfortunately, it seems that it is not a simple matter to write Sakai providers that simply answer authentication and access control queries on the basis of available Shibboleth attributes, which is what we were looking for. The reason is that Sakai does not provide access to the incoming request context where the Shibboleth attributes are provided to an application. It seems that Sakai, being primarily responsible for handling incoming HTTP requests, assumes that it has extracted all the useful information, and does not allow that provider components might also need access to the request context.

5. References

  1. http://www.dr-chuck.com/talks.php?id=67

  2. http://source.sakaiproject.org/release/2.1.2/javadoc/

  3. http://cvs.sakaiproject.org/release/2.1.2/javadoc/org/sakaiproject/service/legacy/user/UserDirectoryProvider.html

  4. https://authdev.it.ohio-state.edu/twiki/bin/view/Shibboleth/AttributeNaming - Shibboleth attribute naming

  5. https://authdev.it.ohio-state.edu/twiki/bin/view/Shibboleth/IdPAttributeConfig - Shibboleth attribute release/mapping

  6. https://authdev.it.ohio-state.edu/twiki/bin/view/Shibboleth/AttributeAcceptancePolicy - Shibboleth attribute acceptance policy


-- GrahamKlyne 2006-06-27 12:10:41

Creative Commons License
The content of this wiki is licensed under the Creative Commons Attribution-ShareAlike 2.0 England & Wales Licence.

OSS Watch is funded by the Joint Information Systems Committee (JISC) and is situated within the Research Technologies Service (RTS) of the University of Oxford.