OwnCloud 8 mit Custom User Backend

Die Einsatzgebiete von OwnCloud sind vielfältig. Man kann seine Kalender synchronisieren, Dateien austauschen oder aber die Arbeit in kleinen Gruppen organisieren. In solchen Fällen hat man häufig schon eine andere Software im Einsatz, sei es ein Wiki, einen Bugtracker oder eine andere Homepage, bei der man sich anmelden muss.

Wünschenswert wäre in diesem Fall, dass man nur einen Benutzernamen und ein Passwort hat, das für alle Dienste gilt. Praktischerweise bietet OwnCloud hier mit Hausmitteln schon eine Lösung, wenn man ein paar Fallstricke beachtet.

Dieses Beispiel geht davon aus, dass bereits eine OwnCloud 7 Installation vorhanden ist und dass als Backend MySQL verwendet wird.

Schritt 1: Vorbereiten der Datenbank

Leider werden bei der Installation von OwnCloud 7 nicht alle Tabellen automatisch angelegt, die für ein Custom User Backend notwendig sind. Daher muss man die Tabelle oc_users_external anlegen:

CREATE TABLE IF NOT EXISTS `oc_users_external` (
    `backend` varchar(128) NOT NULL,
    `uid` varchar(64) NOT NULL,
    `displayname` varchar(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Schritt 2: Erstellen eines eigenen Backends

Im Verzeichnis apps/user_external/lib/ finden sich einige Beispiele (z.B. imap.php), die man für seine eigenen Zwecke umschreiben kann. Ein Minimalbeispiel sieht so aus (Man ersetze MYSITE durch einen eigenen Identifier)

<?php 
class OC_User_MYSITE extends \OCA\user_external\Base{
    private $host;
    public function __construct($host, $secure=false) {
        $this->host=$host;
        parent::__construct('mysite://' . $this->host);
    }

    public function checkPassword($uid, $password) {
        $url = 'http://'.$this->host.'/cloud_auth';
        $data = array('password' => $password, 'user' => $uid);

        $options = array(
            'http' => array(
                'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                'method' => 'POST',
                'content' => http_build_query($data, '', '&amp;'),
            ),
        );

        $result = file_get_contents($url, false, stream_context_create($options));
    
        if(!$result)
            return false;

        $uid = trim($result);
        $this->storeUser($uid);
        return $uid;
    }
}

Auf seiner Webseite muss man nun noch ein Skript erstellen, das auf die Route /cloud_auth hört und den Benutzernamen sowie das Passwort entgegen nimmt. Das Skript muss prüfen, ob beide korrekt sind und (sofern dem so ist) den Benutzernamen als Antwort zurückgeben. Ansonsten liefert man einfach eine 404 Fehlermeldung. Mit dem betagten Symfony1 Framework mit sfGuard Plugin kann das ganze so aussehen:

  public function executeAuth(sfWebRequest $request)
  {
    $username = $request->getParameter('user');
    $password = $request->getParameter('password');

    if($username && $password)
      if ($user = sfGuardUserPeer::retrieveByUsername($username))
        if ($user->getIsActive() && $user->checkPassword($password))
          return $this->renderText($username);

    $this->forward404();
  }

Für andere Frameworks sollte das Skript leicht anzupassen sein.

Schritt 3: Konfigurationsdatei

Die Konfigurationsdatei von OwnCloud muss noch angepasst werden, um das Backend zu nutzen. An dieser Stelle findet sich was in der OwnCloud-Doku: OwnCloud Documentation: Custom User Backend.

Kurz zusammengefasst muss in die Konfiguration folgender Block aufgenommen werden:

<?php
$CONFIG = array (
    /*[...]*/
    'user_backends' => array (
        0 => array (
            "class"     => "OC_User_MYSITE",
            "arguments" => array (
                0 => 'www.ff-holsterhausen.de'
            ),
        ),
    ),
    /*[...]*/
);

Schritt 4: Ein paar Hacks

Eigentlich sollte (laut Anleitung) an dieser Stelle die ganze Sache laufen. Leider kann man sich aber noch nicht anmelden und in den Logs tauchen komische Fehlermeldungen auf:

{"app":"core","message":"User backend OC_User_MYSITE not found.","level":3,"time":"..."}

Irgendwie klappt der Autoloader an dieser Stelle nicht richtig. Das kann man aber relativ einfach fixen. Hierzu geht man in die Datei lib/private/user.php etwa zu Zeile 150 und fügt die require_once... Zeile einfach ein sodass dort folgendes steht:

        public static function setupBackends() {
                OC_App::loadApps(array('prelogin'));
                $backends = OC_Config::getValue('user_backends', array());

                require_once(dirname(__FILE__).'/../../apps/user_external/lib/mysite.php');

                foreach ($backends as $i => $config) {

Fertig! Nun sollte die Authentifizierung klappen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.