Autor Zpráva
liborse
Profil
Předem podotýkám, že už druhým dnem hledám jako zběsilý, ale nic, co jsem našel, nefunguje. ;) Použil jsem vyhledávání zde i na google.

A teď k problému - na intranetu bych do určité aplikace chtěl udělat automatické přihlašování. Není třeba nutit uživatele, aby se přihlásili do Windows a pak ještě do aplikace. Firma, pro kterou pracuji, využívá active directory, zmiňovaná aplikace běží na IIS7 na bázi PHP, nicméně zde fungují i aspx soubory. Bohužel já asp vůbec neumím, ale napadlo mě, že by možná přes něj šlo získat údaje o uživateli, např. že by ho aplikace získala přes ajax. Zjistit přihlášeného uživatele jsem zkoušel i přes js, opět nic.

Vím, že je to silně amatérské, vím, že to možná nějak souvisí s LDAP (opět nový termín pro mě), ale velmi bych ocenil, kdybyste mě nakopli, kam dál. Díky moc!
Enko
Profil
Jsou dvě řešení. Kažedé más vé výhody a nevýhody.
První řešení je možné pouze v případě, že máte striktně zavedené používání IE, ve výchozím nastavení stačí. A můžeš pro případy například přes GPO zakázat měnit určitá nastavení. Konkrétně aby si uživatelé vypli možnost NTLM autentizace. Ale s tímto jsem se za několikaletou praxi nesetkal :-) Při této variantě si PHP skript vezme z hlaviček IE informaci o přihlášeném uživateli do IE, se kterým pak můžeš pracovat. Viz tento odkaz: http://siphon9.net/loune/2007/10/simple-lightweight-ntlm-in-php/ Ovšem zde nedochází ke skutečnému zjišťování, zda je uživatel v pořádku vůči AD, atd... Prostě jenom vezmeš z hlaviček název uživatele/počítače nebo domény.

Druhým řešením je možnost skutečné autentizace vůči AD, a na to si musíš zprovoznit LDAP (ideálně však LDAPS, aby ti nelítali hesla po síti v plaintextu) k AD a až to budeš mít, tak můžeš využívat skutečné ověření vůči AD.
Zde posílám celé řešení, včetně přihlašovacího formuláře a ošetření proti Injection útoku:
<?php
//funkce na overeni uzivatelskeho prihlase do AD
function authUserAD($username, $password, $DomainName="domena.local", $ldap_server="ldap://192.168.1.2") { 
  $auth_user = $username."@".$DomainName;
  if($connect = ldap_connect($ldap_server)){
    ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
    if(ldap_bind($connect, $auth_user, $password)) {
      ldap_close($connect);
      return(true);
    }
  }
  ldap_close($connect);
  return(false);
}

//funkce na vycisteni vstupu do LDAP
/**
 * function ldap_escape
 * @author Chris Wright
 * @version 2.0
 * @param string $subject The subject string
 * @param bool $dn Treat subject as a DN if TRUE
 * @param string|array $ignore Set of characters to leave untouched
 * @return string The escaped string
 */
function ldap_escape ($subject, $dn = TRUE, $ignore = NULL) {

    // The base array of characters to escape
    // Flip to keys for easy use of unset()
    $search = array_flip($dn ? array('\\', ',', '=', '+', '<', '>', ';', '"', '#') : array('\\', '*', '(', ')', "\x00"));

    // Process characters to ignore
    if (is_array($ignore)) {
        $ignore = array_values($ignore);
    }
    for ($char = 0; isset($ignore[$char]); $char++) {
        unset($search[$ignore[$char]]);
    }

    // Flip $search back to values and build $replace array
    $search = array_keys($search); 
    $replace = array();
    foreach ($search as $char) {
        $replace[] = sprintf('\\%02x', ord($char));
    }

    // Do the main replacement
    $result = str_replace($search, $replace, $subject);

    // Encode leading/trailing spaces in DN values
    if ($dn) {
        if ($result[0] == ' ') {
            $result = '\\20'.substr($result, 1);
        }
        if ($result[strlen($result) - 1] == ' ') {
            $result = substr($result, 0, -1).'\\20';
        }
    }

    return $result;
}

//jdeme zpracovat
if($_SERVER["REQUEST_METHOD"]  == "POST"){
  //kontrola vyplnenosti vstupnich poli
  if(empty($_POST["username"])){$chyba[] = "<p class=\"error\">Vyplňte uživatelské jméno.</p>";}
  if(empty($_POST["password"])){$chyba[] = "<p class=\"error\">Vyplňte heslo.</p>";}

  
  //vypsani chyb ze vstupnich poli, pokud nejake jsou
  if(is_array($chyba)){
    foreach($chyba as $value){
      echo $value;
    }
  }
  //ulozit data do databaze a nahrat obrazek
  else{
    //osetreni vstupu proti LDAP Injection a odstraneni mezer
    $username = ldap_escape(trim($_POST["username"]));
    $password = ldap_escape(trim($_POST["password"]));
    
    //jdeme se prihlasit
    if(authUserAD($username, $password)){
      echo "Přihlášení je OK";    
    }
    else{
      echo "Přihlášení selhalo";
    }
  }
}

?>
 <table>
 <form action="" method="POST">
   <tr>
    <td><label for="username">Uživatelské jméno: </label></td>
    <td><input id="username" type="text" name="username" size="30" maxlength="99" value="<?php if(isset($_POST["username"])){echo htmlspecialchars($_POST["username"]);} ?>"/></td> 
   </tr>
   <tr>
    <td><label for="password">Heslo: </label></td>
    <td><input id="password" type="password" name="password" size="30" maxlength="99"/></td>        
   </tr>
   <tr>
    <td>&nbsp;</td>
    <td><input type="submit" name="submit" value="&nbsp;&nbsp;&nbsp;&nbsp;Přihlásit&nbsp;&nbsp;&nbsp;&nbsp;" /></td>
   </tr>
 </form>
 </table>
Pokud budeš potřebovat pomoct se zprovozněním, LDAP z PHP nebo čímkoliv do detailu na toto téma, dej vědět :-) Samozřejmě můžeš na automatické přihlášení využívat kombinaci obojího.

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: