Log masuk LDAP tanpa kata laluan dan dapatkan maklumat pengguna menggunakan tiket Kerberos dalam PHP
P粉071743732
P粉071743732 2024-03-26 10:40:55
0
1
478

Saya cuba melaksanakan SSO pada beberapa tapak intranet syarikat kami menggunakan FreeIPA/Kerberos. Tetapi terdapat sedikit maklumat mengenai topik ini.

Saya mempunyai tiga mesin yang sedang berjalan dalam rangkaian ujian saya:

  1. PelayanIPA v4.9.8 Percuma pada Centos 8 Stream
  2. Pelayan web pada Debian 11 (Apache v2.4.53, PHP v7.4.28)
  3. Xubuntu 22.04 pelanggan dengan Kinit dan Firefox

Kinit, log masuk Unix dan Apache Kerberos Auth berfungsi. Pelayar Firefox pada sistem klien boleh log masuk ke FreeIPA WebConfig tanpa kata laluan (menggunakan Kerberos Ticket). Saya kini mahu mengalihkan fungsi ini ke halaman intranet kami. Sehingga kini, log masuk ke halaman ini berdasarkan log masuk LDAP tradisional. Dengan sedikit pelarasan pada skrip log masuk, pengguna kini boleh log masuk ke pelayan FreeIPA baharu. Bagaimanapun, dia masih memerlukan kata laluan, tetapi terima kasih kepada tiket Kerberos, kata laluan itu sebenarnya tidak diperlukan lagi.

Persoalannya, apakah rupa log masuk tanpa kata laluan?

Coretan fungsi skrip log masuk:

<?php
$username = $_SERVER['PHP_AUTH_USER'];
$password = 'password';

$ldap_rdn  = 'uid='.$username.',cn=users,cn=accounts,dc=exampletest,dc=de';
$ldap_server = ldap_connect('ldap://ipa.exampletest.de:389');

ldap_set_option($ldap_server, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap_server, LDAP_OPT_REFERRALS, 0);

if ($ldap_server) {
  $ldap_bind = @ldap_bind($ldap_server, $ldap_rdn, $password);
  if ($ldap_bind) {
    $search = array("uid","givenname","sn","mail","uidnumber","gidnumber");
    $result = ldap_search($ldap_server, $ldap_rdn, "mail=$username*", $search);
    $info = ldap_get_entries($ldap_server, $result);

    print_r($info);
  }
}
?>

Sekarang saya ada dua fikiran:

  1. Saya boleh menggunakan ldap_sasl_bind() dan bukannya ldap_bind(), tetapi fungsi itu tidak didokumenkan pada php.net (https://www.php.net/manual/en/function.ldap-sasl-bind.php). Jika sesiapa tahu cara menggunakan ciri ini saya akan berterima kasih.
  2. Saya juga gembira jika saya boleh menjalankan ldap_search() tanpa kata laluan untuk mendapatkan maklumat pengguna (nama penuh, e-mel, dll.).

Terima kasih banyak-banyak terlebih dahulu.

Editor:

Kedua-dua VM Pelayan Web dan VM Pelanggan dimulakan melalui "ipa-client-install". Selain itu, pelayan web telah mendaftarkan perkhidmatan apache (ipa service-add HTTP/ebook.exampletest.de).

Konfigurasi apache juga menggambarkan ini:

<Directory /var/www/ebook/>
        AuthType                GSSAPI
        AuthName                "eBook Login"
        GssapiCredStore         keytab:/etc/apache2/http.keytab
        GssapiAllowedMech       krb5
        GssapiBasicAuthMech     krb5
        GssapiImpersonate       On
        GssapiDelegCcacheDir    /run/apache2/clientcaches
        GssapiLocalName         On
        
        # for production set to on:
        GssapiSSLonly           Off
        GssapiNegotiateOnce     Off
        
        GssapiUseSessions       On
        Session                 On
        SessionCookieName       gssapi_session path=/private;httponly;secure;
        Require                 valid-user
    </Directory>
Seperti yang telah saya nyatakan, pengesahan pengguna nampaknya berfungsi seperti ini (client(自己的票) > web 服务(自己的票) > ipa server). Jika tidak pelayan apache tidak akan mengembalikan nama pengguna ldap/kerberos saya. Atau adakah saya kehilangan sesuatu yang penting di sini? Adakah terdapat cara lain untuk menguatkuasakan pengesahan ini?

Output: <?php print_r($_SERVER) ?> (dipintas)

[GSS_MECH] => Negotiate/krb5
[GSS_NAME] => test@EXAMPLETEST.DE
[REMOTE_USER] => test
[AUTH_TYPE] => Negotiate
[PHP_AUTH_USER] => test

P粉071743732
P粉071743732

membalas semua(1)
P粉614840363

Pastikan pelayan web anda mempunyai tiket betul Kerberos.

Biasanya, pengesahan Kerberos hanya menghantar tiket yang sah hanya untuk pelayan itu, bukannya selimut tiket "semua". Apabila pelanggan membuat pengesahan ke apl web anda, anda hanya mendapat tiket untuk HTTP/webapp.example.tld dan anda sebenarnya tidak boleh menggunakannya untuk mengakses LDAP bagi pihak pengguna.

Jika anda perluuntuk mengakses LDAP bagi pihak pengguna, anda mempunyai beberapa pilihan:

  • Aplikasi web boleh mempunyai kelayakan direktori LDAP mereka sendiri. Ini mungkin cara yang paling mudah. Aplikasi web boleh menggunakan pengikatan kata laluan standard atau pengikatan Kerberos (SASL) menggunakan tiket mereka sendiri yang diperoleh daripada tab kekunci.

    • LDAP juga menyokong "penyamaran", di mana aplikasi web akan mengesahkan menggunakan bukti kelayakannya sendiri, tetapi juga nyatakan "ID Kebenaran" (authzid) untuk menentukan akaun yang anda akan diberikan akses.

      Sebagai contoh, jika anda mengesahkan sebagai "webapp" tetapi menentukan authzid "myuser" (dan jika pelayan LDAP membenarkannya ), maka anda akan mendapat kebenaran yang "myuser" biasanya ada - bukan "webapp" bagi mereka .

  • Pengesahan HTTP Rundingan (SPNEGO) untuk aplikasi web boleh membolehkan "delegasi". Delegasi melakukan memindahkan tiket induk krbtgt ke pelayan web, yang kemudiannya meletakkannya ke dalam cache tiket sementara dan menjadikannya tersedia untuk persekitaran aplikasi web anda.

    Namun, terdapat beberapa masalah dengan delegasi:

    1. Ini akan memperlahankan setiap permintaan HTTP kerana pelanggan perlu meminta tiket krbtgt baharu dengan bendera "forward" (melainkan pelayan web boleh menggunakan cth. kuki untuk mengelak meminta pengesahan rundingan) untuk permintaan lanjut, mis. dengan mod_auth_gssapi dengan "session "mod).

    2. Ia memerlukan aplikasi web dipercayai tinggi kerana ia akan menyimpan tiket wildcard untuk setiap pengguna yang mengaksesnya (termasuk pentadbir) - walaupun aplikasi web itu sendiri dipercayai untuk tidak menyalahgunakannya, mereka masih boleh dikompromi oleh pelayan.

    3. Kebanyakan API yang menggunakan Kerberos (termasuk ldap_sasl_bind()) menjangkakan KRB5CCNAME pembolehubah persekitaran menunjuk ke cache tiket. Tetapi pembolehubah persekitaran adalah skop proses, jadi ia boleh dibocorkan dalam permintaan yang tidak berkaitan apabila PHP menggunakan semula proses yang sama (atau lebih teruk, jika anda menggunakan mod_php untuk menjalankan aplikasi web anda dalam proses Apache).

    Dalam AD, ini secara khusus dipanggil "delegasi tanpa kekangan" sejak AD memperkenalkan variasi lain.

  • Aplikasi web boleh menggunakan S4U2Proxy aka "delegasi terhad" untuk mencipta tiket bagi pihak pengguna untuk set perkhidmatan terhad tertentu (mis. FreeIPA boleh mengehadkan mereka hanya untuk mengakses ldap/foo.example.com).

    Ini agak rumit (PHP tidak mempunyai API untuk ini - anda mungkin perlu menjananya dengan bendera yang betul kinit), dan masih mempunyai potensi isu yang sama seperti kebocoran permintaan silang KRB5CCNAME.

Untuk pengesahan Kerberos biasa, penggunaannya adalah seperti berikut:

ldap_sasl_bind($conn, null, null, "GSSAPI");

Itu sahaja. Mekanisme GSSAPI SASL menjangkakan persekitaran sudah mempunyai tiket Kerberos tersedia (cth. melalui $KRB5CCNAME atau melalui gss-proxy), dan ia akan menggunakan mana-mana tiket yang terdapat di sana untuk pengesahan.

Jika anda ingin menggunakan penyamaran (dengan mengandaikan persediaan dalam pelayan LDAP), anda mesti menyatakan authz_id:

ldap_sasl_bind($conn, null, null, "GSSAPI", null, null, $theuser);

Kebanyakan ldap_*() fungsi PHP adalah pembungkus langsung perpustakaan C libldap, jadi dokumentasinya boleh digunakan sebagai rujukan separa.

Nampaknya contoh anda sudah menyatakan DN tepat pengguna, jadi lulus mail 进行额外过滤 - 只需在读取邮件时使用 objectClass=*DN tertentu nampaknya tidak diperlukan. Selain itu, apabila anda ingin membaca DN tertentu, gunakan ldap_read() untuk carian "asas" dan bukannya carian subtree.

Tidak, bukan itu yang berlaku. Nama pengguna anda (iaitu, pelanggan Kerberos prinsipal) disimpan dalam tiket pelanggan, jadi pelayan web mengetahuinya serta-merta selepas menyahsulit tiket tanpa perlu bercakap dengan IPA.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan