remote autorisierung - contenido auth-prozess

Fragen zur Installation von CONTENIDO 4.9? Probleme bei der Konfiguration? Hinweise oder Fragen zur Entwicklung des Systemes oder zur Sicherheit?
Antworten
martin2002
Beiträge: 41
Registriert: Fr 31. Okt 2003, 02:16
Wohnort: Potsdam
Kontaktdaten:

remote autorisierung - contenido auth-prozess

Beitrag von martin2002 » So 16. Jan 2005, 17:16

Hallo,

ich habe vor (bzw. es getan) für das frontend eine remote validierung für logindaten zu integrieren... (soll heißen auf einem anderen server als dem webserver läuft ein programm, welches die logins überprüft)
Notwendig ist dies für mich, da wir unabhängig vom Webserver ein Netzwerk laufen haben, wo sehr viele Benutzer eingebunden sind und es schlichtweg zu kompliziert wäre diese alle in die conteniod-db einzufügen und dann auch noch die kennwörter aktuell zu halten...

naja... lange rede kurzer sinn:
Der Spaß will nicht so richtig.

Was habe ich gemacht:
  • ich habe die allgemeine auth-klasse um einen funktionsdummy

    Code: Alles auswählen

    function auth_remotevalidatelogin() { ; }
    erweitert
  • den code der funktion hab ich in "Contenido_Frontend_Challenge_Crypt_Auth" klasse eingebunden.
    Sie gibt false bei fehlgeschlagenem und bei erfolgreichem login eine $uid in der form: "srvauth_{username}" zurück. Die perms werden auf "" gesetzt.
  • ich rufe die funktion nicht von "$auth->start()" auf sondern aus "auth_validatelogin()"
Für mich sieht das vollständig aus, dennoch werden die logins nicht akzeptiert. (Ich habe auch mal die $uid eines frontend users für den remote-auth-vorgang statisch als $uid festgelegt, anstelle meiner "remote-uid" - funktionierte auch nicht)
Ich vermute also mal da fehlt noch etwas... Kann mir jemand sagen was ich vergessen hab?

kann mir jemand erklären, wie der auth-prozess abläuft?
ich habe ihn wie in dem genannten trhead beschrieben erweitert... gebe eine uid zurück! (ist es hier egal, ob diese uid in der datenbank vorkommt oder macht das probleme?)
trotz festgelegter uid komme ich über den "remote" weg nicht rein... übernimmt er die nicht in die session? :shock:

:?:

thx
Martin

emergence
Beiträge: 10641
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence » Mo 17. Jan 2005, 19:51

verschoben...

wie gesagt intressiert mich auch... (viel zu wenig zeit um sich alles anzusehen)

vielleicht hat timo ein paar tipps ... ;-)
*** make your own tools (wishlist :: thx)

martin2002
Beiträge: 41
Registriert: Fr 31. Okt 2003, 02:16
Wohnort: Potsdam
Kontaktdaten:

Beitrag von martin2002 » Mo 17. Jan 2005, 20:03

... ist es eigentlich normal, das die start() funktion zweimal aufgerufen wird?
beim ersten mal mach er den login prozess (state = 3) und gibt eine uid zurück...
dann ruft er die funktion nochmal auf (von wo eigentlich!?) und hier gibt dann is_authenticated() false zurück (=> state = 1), weil die uid für diesen run nicht mehr festgelegt ist. :?: :?: :?:
Planung ist die Ersetzung des Zufalls durch den Irrtum ;-)

timo
Beiträge: 6284
Registriert: Do 15. Mai 2003, 18:32
Wohnort: Da findet ihr mich nie!
Kontaktdaten:

Beitrag von timo » Mo 31. Jan 2005, 11:58

hmm tips hab ich leider keine...

martin2002
Beiträge: 41
Registriert: Fr 31. Okt 2003, 02:16
Wohnort: Potsdam
Kontaktdaten:

Beitrag von martin2002 » Mo 31. Jan 2005, 22:35

hm... ok, trotzdem danke.

aber gibts da nicht jemand, der weiß wie diese autorisierung funktioniert? :?
Planung ist die Ersetzung des Zufalls durch den Irrtum ;-)

emergence
Beiträge: 10641
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence » Mi 2. Feb 2005, 13:32

keine ahnung ob das hilft aber in der 4.5.2alpha
-> docs\techref\backend\backend.plugauth.html
sieh dir das mal an...
*** make your own tools (wishlist :: thx)

martin2002
Beiträge: 41
Registriert: Fr 31. Okt 2003, 02:16
Wohnort: Potsdam
Kontaktdaten:

Beitrag von martin2002 » Mi 2. Feb 2005, 20:57

also das klingt ja schon mal nicht schlecht...
aber es hilft mir nur, wenn es mehr oder weniger unkompliziert ist es in die 4.4.4er version zu integrieren (ich hab ne ganze menge veränder und kann deswegen kein update machen).

also: was müsste ich tun um diesen mechanismus in die 4.4.4 verision zu eihzubinden?

thx
Martin
Planung ist die Ersetzung des Zufalls durch den Irrtum ;-)

emergence
Beiträge: 10641
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence » Do 3. Feb 2005, 11:30

martin2002 hat geschrieben:also: was müsste ich tun um diesen mechanismus in die 4.4.4 verision zu eihzubinden?
hmm...
ich schätze mal das ein großteil der änderungen in der conlib/local.php
statt gefunden hat... (auth.inc wäre ebenso möglich...)
such dort mal nach $auth_handlers und ich glaub es gibt dort ganz am ende ne neue funktion -> register_auth_handler

zusätzlich muss du noch dafür sorgen das eine config.local.php eingebunden werden kann...
am ende der config.php solltest du folgendes ergänzen

Code: Alles auswählen

if (file_exists(dirname(__FILE__) . "/config.local.php"))
{
	include_once( dirname(__FILE__) . "/config.local.php");
}
wohlgemerkt ist alles theorie getestet hab ich das nicht...

es sollte dann aber so wie in der doku beschrieben ist funktionieren...
*** make your own tools (wishlist :: thx)

martin2002
Beiträge: 41
Registriert: Fr 31. Okt 2003, 02:16
Wohnort: Potsdam
Kontaktdaten:

Beitrag von martin2002 » Do 3. Feb 2005, 18:06

bin ich dabei...

ich sag dann bescheid, ob's erfolgreich war.

thx
Martin
Planung ist die Ersetzung des Zufalls durch den Irrtum ;-)

martin2002
Beiträge: 41
Registriert: Fr 31. Okt 2003, 02:16
Wohnort: Potsdam
Kontaktdaten:

Beitrag von martin2002 » So 6. Feb 2005, 13:59

ja hat ganz toll funktioniert :D

brauchte bloß die neuen funktionen einbinden und das synchronisationsscript schreiben (wie im techref beschrieben)... mal abgesehen von ein paar kleinen anpassungen in der 4.5er local.php auf die 4.4er datenbank.

ich hatte dann aber noch das problem, dass die nuter im frontend nicht engelooggt blieben beim seitenwechsel... trat auch auf mit vom contenido selbst erstellten nutzern...

ich hab dann einfach an verschiedenen stellen in der auth.inc (immer nach erfolgreichem login) und am ende der logout() funktion ein $sess->freeze() eingefügt und dann ging das auch...

ist jetzt nur die frage ob sich das nachteilig auf das backend auswirkt?

hier mal meine auth.inc (die betreffenden stellen sind mit "krelli edit" markiert

Code: Alles auswählen

<?php
/*
 * Session Management for PHP3
 *
 * Copyright (c) 1998-2000 NetUSE AG
 *                    Boris Erdmann, Kristian Koehntopp
 * Copyright (c) 1999-2000 Internet Images srl
 *                    Massimiliano Masserelli
 *
 * $Id: auth.inc,v 1.1.1.1 2002/07/21 08:35:41 root Exp $
 *
 */ 

class Auth {
  var $classname = "Auth";
  var $persistent_slots = array("auth");
  
  var $lifetime = 15;             ## Max allowed idle time before
                                  ## reauthentication is necessary.
                                  ## If set to 0, auth never expires.
  
  var $refresh = 0;               ## Refresh interval in minutes. 
                                  ## When expires auth data is refreshed
                                  ## from db using auth_refreshlogin()
                                  ## method. Set to 0 to disable refresh

  var $mode = "log";              ## "log" for login only systems,
                                  ## "reg" for user self registration

  var $magic = "";                ## Used in uniqid() generation

  var $nobody = false;            ## If true, a default auth is created...

  var $cancel_login = "cancel_login"; ## The name of a button that can be 
                                      ## used to cancel a login form

  ## End of user qualifiable settings.

  var $auth = array();            ## Data array
  var $in   = false;
  var $db;

  ##
  ## Initialization
  ##
  function start() {
    $cl = $this->cancel_login;
    global $sess, $$cl;

    ## This is for performance, I guess but I'm not sure if it could
    ## be safely removed -- negro
    if (! $this->in) {
      $sess->register("auth");
      $this->in = true;
    }
    
    ## back compatibility: if d_c is set, create db object
    if(isset($this->database_class)) {
      $class = $this->database_class;
      $this->db = new $class;
    }

    # Check current auth state. Should be one of
    #  1) Not logged in (no valid auth info or auth expired)
    #  2) Logged in (valid auth info)
    #  3) Login in progress (if $$cl, revert to state 1)
    if ($this->is_authenticated()) {
      $uid = $this->auth["uid"];

      switch ($uid) {
        case "form":
          # Login in progress
          if ($$cl) {
            # If $$cl is set, delete all auth info 
            # and set state to "Not logged in", so eventually
            # default or automatic authentication may take place
            $this->unauth();
            $state = 1;
          } else {
            # Set state to "Login in progress"
            $state = 3;
          }
          break;
        default:
          # User is authenticated and auth not expired
          $state = 2;
          break;
      }
    } else {
      # User is not (yet) authenticated
      $this->unauth();
      $state = 1;
    }
	
    switch ($state) {
      case 1:
        # No valid auth info or auth is expired
        
        # Check for user supplied automatic login procedure 
        if ( $uid = $this->auth_preauth() ) {
          $this->auth["uid"] = $uid;
          $this->auth["exp"] = time() + (60 * $this->lifetime);
          $this->auth["refresh"] = time() + (60 * $this->refresh);
		  $sess->freeze(); // krelli edit
          return true;
        }
        
        # Check for "log" vs. "reg" mode
        switch ($this->mode) {
          case "yes":
          case "log":
            if ($this->nobody) {
              # Authenticate as nobody
              $this->auth["uid"] = "nobody";
              # $this->auth["uname"] = "nobody";
              $this->auth["exp"] = 0x7fffffff;
              $this->auth["refresh"] = 0x7fffffff;
			  $sess->freeze(); // krelli edit
              return true;
            } else {
              # Show the login form
              $this->auth_loginform();
              $this->auth["uid"] = "form";
              $this->auth["exp"] = 0x7fffffff;
              $this->auth["refresh"] = 0x7fffffff;
              $sess->freeze();
              exit;
            }
            break;
          case "reg":
           if ($this->nobody) {
              # Authenticate as nobody
              $this->auth["uid"] = "nobody";
              # $this->auth["uname"] = "nobody";
              $this->auth["exp"] = 0x7fffffff;
              $this->auth["refresh"] = 0x7fffffff;
              return true;
            } else {
            # Show the registration form
              $this->auth_registerform();
              $this->auth["uid"] = "form";
              $this->auth["exp"] = 0x7fffffff;
              $this->auth["refresh"] = 0x7fffffff;
              $sess->freeze();
              exit;
            }
            break;
          default:
            # This should never happen. Complain.
            echo "Error in auth handling: no valid mode specified.\n";
            $sess->freeze();
            exit;
        }
        break;
      case 2:
        # Valid auth info
        # Refresh expire info
        ## DEFAUTH handling: do not update exp for nobody.
        if ($uid != "nobody") {
          $this->auth["exp"] = time() + (60 * $this->lifetime);
//		  echo "<br>state-two-freeze:<br>";
//		  $sess->freeze(); // krelli edit
		}
        break;
      case 3:
        # Login in progress, check results and act accordingly
        switch ($this->mode) {
          case "yes":
          case "log":
            if ( $uid = $this->auth_validatelogin() ) {
              $this->auth["uid"] = $uid;
              $this->auth["exp"] = time() + (60 * $this->lifetime);
              $this->auth["refresh"] = time() + (60 * $this->refresh);
			  $sess->freeze(); // krelli edit
              return true;
            } else {
              $this->auth_loginform();
              $this->auth["uid"] = "form";
              $this->auth["exp"] = 0x7fffffff;
              $this->auth["refresh"] = 0x7fffffff;
              $sess->freeze();
              exit;
            }
            break;
          case "reg":
            if ($uid = $this->auth_doregister()) {
              $this->auth["uid"] = $uid;
              $this->auth["exp"] = time() + (60 * $this->lifetime);
              $this->auth["refresh"] = time() + (60 * $this->refresh);
              return true;
            } else {
              $this->auth_registerform();
              $this->auth["uid"] = "form";
              $this->auth["exp"] = 0x7fffffff;
              $this->auth["refresh"] = 0x7fffffff;
              $sess->freeze();
              exit;
            }
            break;
          default:
            # This should never happen. Complain.
            echo "Error in auth handling: no valid mode specified.\n";
            $sess->freeze();
            exit;
            break;
        }
        break;
      default:
        # This should never happen. Complain.
        echo "Error in auth handling: invalid state reached.\n";
        $sess->freeze();
        exit;
        break;
    }
  }

  function login_if( $t ) {
    if ( $t ) {
      $this->unauth();  # We have to relogin, so clear current auth info
      $this->nobody = false; # We are forcing login, so default auth is 
                             # disabled
      $this->start(); # Call authentication code
    }
  }

  function unauth($nobody = false) {
    $this->auth["uid"]   = "";
    $this->auth["perm"]  = "";
    $this->auth["exp"]   = 0;

    ## Back compatibility: passing $nobody to this method is
    ## deprecated
    if ($nobody) {
      $this->auth["uid"]   = "nobody";
      $this->auth["perm"]  = "";
      $this->auth["exp"]   = 0x7fffffff;
    }
  }
  

  function logout($nobody = "") {
    global $sess;
    
    $sess->unregister("auth");
    unset($this->auth["uname"]);
    $this->unauth($nobody == "" ? $this->nobody : $nobody);
	$sess->freeze(); // krelli edit
  }

  function is_authenticated() {
    if (
      isset($this->auth["uid"])
        &&
      $this->auth["uid"] 
        && 
      (($this->lifetime <= 0) || (time() < $this->auth["exp"]))
    ) {
      # If more than $this->refresh minutes are passed since last check,
      # perform auth data refreshing. Refresh is only done when current
      # session is valid (registered, not expired).
      if (
        ($this->refresh > 0) 
         && 
        ($this->auth["refresh"])
         && 
        ($this->auth["refresh"] < time())
      ) {
        if ( $this->auth_refreshlogin() ) {
          $this->auth["refresh"] = time() + (60 * $this->refresh);
        } else {
          return false;
        }
      }
      return $this->auth["uid"];
    } else {
      return false;
    }
  }
    
  ########################################################################
  ##
  ## Helper functions
  ##
  function url() {
    return $GLOBALS["sess"]->self_url();
  }

  function purl() {
    print $GLOBALS["sess"]->self_url();
  }

  ## This method can authenticate a user before the loginform
  ## is being displayed. If it does, it must set a valid uid 
  ## (i.e. nobody IS NOT a valid uid) just like auth_validatelogin,
  ## else it shall return false.

  function auth_preauth() { return false; }
  
  ##
  ## Authentication dummies. Must be overridden by user.
  ##
  
  function auth_loginform() { ; }

  function auth_validatelogin() { ; }
  
  function auth_refreshlogin() { ; }

  function auth_registerform() { ; }

  function auth_doregister() { ; }
}
?>
Planung ist die Ersetzung des Zufalls durch den Irrtum ;-)

emergence
Beiträge: 10641
Registriert: Mo 28. Jul 2003, 12:49
Wohnort: Austria
Kontaktdaten:

Beitrag von emergence » Mo 7. Feb 2005, 12:58

martin2002 hat geschrieben:ich hab dann einfach an verschiedenen stellen in der auth.inc (immer nach erfolgreichem login) und am ende der logout() funktion ein $sess->freeze() eingefügt und dann ging das auch...

ist jetzt nur die frage ob sich das nachteilig auf das backend auswirkt?
das $sess->freeze() bewirkt nichts anderes wie das die variablen in der db gesichert werden... am ende einer jeder seite wird ebenso ein $sess->freeze() ausgelöst -> page_close();
weiterleitungen haben an sich den nachteil das genau diese sicherung nicht stattfindet... da meist das script gar nicht so weit kommt um die funktion page_close auszuführen...

auswirkungen im backend dürfte das nicht haben... wäre aber möglich das es bei der ausführung der scripts etwas mehr zeit benötigt...
*** make your own tools (wishlist :: thx)

martin2002
Beiträge: 41
Registriert: Fr 31. Okt 2003, 02:16
Wohnort: Potsdam
Kontaktdaten:

Beitrag von martin2002 » Mo 7. Feb 2005, 20:09

emergence hat geschrieben:$sess->freeze() bewirkt nichts anderes wie das die variablen in der db gesichert werden... am ende einer jeder seite wird ebenso ein $sess->freeze() ausgelöst -> page_close();
ist erstmal klar... aber dann müssen die auth-daten nicht richtig in der klasse abgelegt worden sein.

grundsätzlich wird der auth-prozess zweimal ausgelößt...
das erste mal nachdem die auth klasse in der page_open() eingebunden wurde wird da start aufgerufen und die loginüberprüfung ausgelößt, wenn eins da ist
das zweite mal durch den call von login_if(true) in der front_content.php...
hier wurde das erfolgreiche login von vorher aber wieder zurückgesetzt (aufruf unauth) $auth->auth["exp"] stand dann auf 0, wodurch in is_authenticated() die überprüfung nicht ausgeführt wurde, da die beiden bedingungen (($this->lifetime <= 0) || (time() < $this->auth["exp"])) nicht zutrafen

daraus folgte, dass die loginform angezeigt wurde und der user nobody in der session gespeicher... mit dem $sess->freeze() nach jedem erfolgreichen login (überall da, wo in der auth.inc "krelli edit" steht) ging das aber :?:
Planung ist die Ersetzung des Zufalls durch den Irrtum ;-)

Antworten