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:
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:
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
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:
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).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.
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:
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:
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.