Implemented SAML plugin for ownCloud
In Confía, the Andalusian Public Universities Identity Federation, cloud based file transfering and hosting services are being evaluated.
Among the players that are being most nice are the University of Sevilla Consigna, Filesender y ownCloud.
ownCloud is essentially a tool to host files but it has a lot more features:
- Security: files are encrypted.
- Usability: versions, drag & drop, change notifications, document viewers and image galleries.
- Interoperability: it offers an API for third party applications and WebDav support.
- Tasks management.
- Contacts management.
- Calendar.
Other important point is the great community behind the project, which is making the software to evolve very quickly.
Because of all this and given the fact it was lacking SAML support, from the Confía federation this contribution has been made and it has been available since last week.
An ownCloud instance has been deployed at the lab environment of Confía and it is available for the pre-production identity providers of the universities.
Since the very beginning of this development there has been a great feedback from the project maintainers. As a proof, the main developer, Frank Karlitschek, has given me commit rights in the ownCloud central repository so I could push the code myself and be responsible of its maintenance from now on.
Hence, the application that add SAML support to ownCloud is already available from the official ownCloud repository hosted at gitorious.
Installation of the user_saml application
Assuming there is an already deployed and configured instance of the SimpleSAMLphp SP the first thing we should do is to get the source code of the user_saml application from the official ownCloud repository. In ownCloud a plugin is called an app:
# git clone git@github.com:pitbulk/apps.git
And we copy that copy into our ownCloud instance:
# cp -R apps/saml_user/apps/
Now we access the administration web interface and enable the SAML application in the applications panel
Configuration
We access the administration panel and go to the SAML application section where we should configure some options.
In the “Basic” tab we can configure:
- simpleSAMLphp related options such as its path and the SP auth source which we want to authenticate with.
- automatic provisioning support and if we want to update the user information every time the user performs the login process.
- a set of internal ownCloud groups that won’t be modified by the SAML application.
- a default group which will be associated with the user in case the SAML group is not found in ownCloud.
In the “Mapping” tab we should configure which attributes from the SAML assertion should be used for the username, email and group of the user in ownCloud..
How it works and usage.
When we enable the SAML application, a new link will be displayed at the bottom of the login form. When this link is activated we will be redirected to the Identity Provider configured in the Service Provider in simpleSAMLphp.
If the “autocreate user” option is enabled, the user will be created if he does not exist in ownCloud user storage. If this option is disabled and the user is not already provisioned in ownCloud, the access will be denied.
If the “update user data after login” option is enabled, the user and group information will be updated in each SAML access. This also handles the case of deprovisioning the groups that are not listed in the SAML assertion anymore with the exception of the group listed in the “groups that will not be unlinked from the user when sync the IdP and the ownCloud”option.
How the ownCloud SAML application was developed?
ownCloud has some of the typical problems we have faced before when “domesticating” an application in a SAML environment. The authentication infraestructure is coupled to the idea of user credentials being a username and a password. This means the password is a required field in the user database table. As you should probably know in a SAML environment the applications never store passwords.
Let’s have a quick look to the function declaration of the authentication base class which will be extended by the authentication backends that are called in the login process:
public static function login( $uid, $password ){
…
$uid = self::checkPassword( $uid, $password );
if ($uid) {
session_generate_id();
self::setUserId($uid);
return true;
}
return false;
}
public static function createUser( $uid, $password )
As you can see the login function in the core of ownCloud calls the checkPassword function wich expect a username and a password, which are provided by the login form. This information is also required to create a user.
We have created an independent view where we redirect the user when he clicks on the SAML link which this code:
// simpleSAMLphp library load
include_once($sspPath.”/lib/_autoload.php”);
// SAML authentication initialization
$auth = new SimpleSAML_Auth_Simple($spSource);
// We force the user to be authenticated
$auth->requireAuth();
// Once he is authenticated and we have a valid session in the SP, we have to make a call to the ownCloud login function but we don’t give it the real username or password.
OC_User::login(‘ ‘, ‘ ‘)
This calls all the authentication backend in cascade until one of them is successful. In this case no one will be successful until we get to the SAML backend. In this backend we check there is a session at the SP and if so, we get the user information and start the session in ownCloud.
public function checkPassword($uid, $password){
if(!$this->auth->isAuthenticated()) {
return false;
}
$attributes = $this->auth->getAttributes();
if (array_key_exists($this->usernameMapping, $attributes)) {
$uid = $attributes[$this->usernameMapping][0];
OC_Log::write(‘saml’,'Authenticated user ‘.$uid,OC_Log::DEBUG);
}
else {
OC_Log::write(‘saml’,'Not found attribute used to get the username (“‘.$this->usernameMapping.’”) at the requested saml attribute
assertion’,OC_Log::DEBUG);
}
return $uid;
}
After that, in the post-login hooks available in ownCloud, we create or update the user if that is required.
As we saw, the password is a required attribute so every time we create a user we generate a random password for him.
Another typical problem when integrating an application in a SAML environment is the Single Log Out problem when this process is started in a different application from ownCloud. In this case the ownCloud log out is not supported.
The fix will require to check the SP session everytime the ownCloud session is checked.
In ownCloud the function that checks if the user is authenticated is this one:
public static function isLoggedIn() { static $is_login_checked = null;
if (!is_null($is_login_checked)) {
return $is_login_checked;
}
if( isset($_SESSION['user_id']) AND $_SESSION['user_id']) {
OC_App::loadApps(array(‘authentication’));
if (self::userExists($_SESSION['user_id']) ){
return $is_login_checked = true;
}
}
return $is_login_checked = false;
}
So if userExists returns false the access is denied.
We initially tried to implement the userExists function in our backend with this code:
public function userExists($uid){
if ($this->auth->isAuthenticated()) {
$attributes = $this->auth->getAttributes();
if (array_key_exists($this->usernameMapping, $attributes)) {
$saml_uid = $attributes[$this->usernameMapping][0];
if($saml_uid && $saml_uid == $uid) {
OC_Log::write(‘saml’,'SAML session found for user ‘.$uid,OC_Log::DEBUG);
return true;
}
}
}
OC_Log::write(‘saml’,'Deleting local session for user ‘.$uid,OC_Log::DEBUG);
unset($_SESSION['user_id']);
return false;
}
The problem is that the global UserExists function calls the authentication backends in a chain and as soon as one of them returns true, the access is allowed and the other backends are not called anymore. So our previous function never get called.
public static function userExists($uid){
foreach(self::$_usedBackends as $backend){
$result=$backend->userExists($uid);
if ($result===true){
return true;
}
}
return false;
}
At this point we didn’t find an easy way to solve this problem without changing ownCloud core code.
Related Posts:
- Research project about async user provisioning based on SAML2.0Proyecto de investigación sobre Provisión asíncrona de usuarios basado en SAML2.0
- Presentado el proyecto CONFIA en la IV Convocatoria de Premios @asLAN a Administraciones y Organismos Públicos
- Como hacer que nuestras aplicaciones de Google Apps autentiquen contra nuestra fuente de usuarios local (base de datos, ldap, etc) usando Uniquid (protocolo SAML 2.0).
Leave a Reply Cancel reply
Categories
- comunication (2)
- contribuciones (9)
- django (5)
- Events (11)
- python (5)
- tamgrambpm (1)
- uniquid (72)
- confia (33)
- documentation (4)
- events-uniquid (28)
- janus (14)
- simplesamlphp (7)
- software (7)
- Virtualization (2)
- Escritorio (1)
- Yaco (9)
- Equipo (4)
- ytourism (2)
Archives
- November 2012 (1)
- July 2012 (2)
- June 2012 (2)
- May 2012 (2)
- April 2012 (1)
- March 2012 (2)
- February 2012 (5)
- January 2012 (3)
- December 2011 (5)
- November 2011 (8)
- October 2011 (7)
- September 2011 (3)
- August 2011 (3)
- July 2011 (1)
- June 2011 (3)
- May 2011 (5)
- March 2011 (2)
- February 2011 (1)
- December 2010 (1)
- November 2010 (2)
- October 2010 (2)
- September 2010 (1)
- June 2010 (3)
- May 2010 (1)
- April 2010 (1)
- March 2010 (3)
- February 2010 (3)
- January 2010 (3)
- December 2009 (6)
- November 2009 (7)
- June 2009 (1)
- May 2009 (1)
- March 2009 (1)
- December 2008 (1)
- June 2008 (1)
- April 2008 (1)
Recent Posts













Buscando cosas sobre Madrid para un proyecto que tengo que hacer en el colegio he dado con vuestro blog y me ha maravillado. Felicidades. Lo pondré entre mis favoritos!.
En primer lugar mis felicitaciones por domesticar una aplicación tan interesante y buena como owncloud.
Mi pregunta va por el estado actual de este plugin, es decir si han desarrollado actualizaciones, ya que estoy muy interesado en probarlo.
Saludos.
Por ahora no se ha desarrollado ninguna actualización
En unos días probaré si el plugin sigue funcionando con la versión actual de owncloud y subiré los cambios pertinentes al repositorio en caso de que sea necesario.
https://github.com/pitbulk/apps/tree/master/user_saml
Felicitaciones también de aquí.
Mi pregunta es si creen que se podría en alguna manera utilizar saml con webdav y clientes mobiles?
Existen clientes webdav con soporte SAML, echa un vistazo a esta wiki que explica como integrar shibboleth con algunos clientes WebDav:
https://wiki.shibboleth.net/confluence/display/SHIB2/WebDAV
In mobile apps there are also sucessfully examples like: http://wiki.developerforce.com/page/Single_Sign-On_for_Desktop_and_Mobile_Applications_using_SAML_and_OAuth
Another question: I added the app and the settings appear, but the nice saml image does not appear on the login page. Apparently
CP\Util::addScript(‘user_saml’, ‘utils’)
in “app.php” does not work.
Your help is much appreciated!
I tested the plugin with the owncloud versions: 4.5beta3 and 4.0.5. What version are you using?. Are u also using my latest saml plugin version (https://github.com/pitbulk/apps/tree/master/user_saml) ?
The login image is added by javascript with the js file loaded at this addScript sentence.
what exactly go wrong? the CP\Util::addScript fail? The js loaded fail?
I’m running owncloud 4.0.7 and just updated to use your latest plugin version from github.
OCP\Util::addScript(‘user_saml’, ‘utils’);
from app.php is executed, but the script is not added (I’m running firebug).
So the
script> type=”text/javascript” src=”/owncloud/apps/user_saml/js/utils.js”>
not appear in the html source code of the main page of your owncloud.
Thats is strange since the load of others javascripts works for you.
Make the following test:
Put the OCP\Util::addScript(‘user_saml’, ‘utils’);
sentence outside the if condition. Maybe you have a problem with the OCP\User::isLoggedIn function and the sentence is never executed due for some reason the isLoggedIn returns true.
Also check if any error appears in your php log.
Hi, I already did this – same result.
I’m afraid that in the new version apps are not available until after login…
Hello,
I try to setup SAML authentification based on your application. It’s works but i have same problem with js inclusion in login form.
I use owncloud version 4.5.2, can i patch this problem ?
Regards, Gamb.
I wil try to test and fix it as soon as possible. Thanks for report it.
Its work fine, thank you !!!
There is definately a lot to learn about this subject. I like all of the points you have made.