Ich versuche, SSO auf einigen Intranetseiten unseres Unternehmens mithilfe von FreeIPA/Kerberos zu implementieren. Es gibt jedoch nur sehr wenige Informationen zu diesem Thema.
In meinem Testnetzwerk laufen drei Maschinen:
Kinit, Unix-Login und Apache Kerberos Auth funktionieren. Der Firefox-Browser auf dem Client-System kann sich ohne Passwort bei FreeIPA WebConfig anmelden (mithilfe des Kerberos-Tickets). Ich m?chte diese Funktionalit?t nun auf unsere Intranetseite verschieben. Bisher basierten die Anmeldungen auf diesen Seiten auf herk?mmlichen LDAP-Anmeldungen. Mit einer leichten Anpassung des Anmeldeskripts k?nnen sich Benutzer jetzt beim neuen FreeIPA-Server anmelden. Allerdings ben?tigt er weiterhin ein Passwort, doch dank des Kerberos-Tickets ist das Passwort eigentlich nicht mehr erforderlich.
Die Frage ist, wie sieht eine passwortlose Anmeldung aus?
Funktioneller Ausschnitt des Anmeldeskripts:
<?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); } } ?>
Jetzt habe ich zwei Gedanken:
Vielen Dank im Voraus.
Herausgeber:
Sowohl die Webserver-VM als auch die Client-VM werden über ?ipa-client-install“ initialisiert. Darüber hinaus hat der Webserver den Apache-Dienst registriert (ipa service-add HTTP/ebook.exampletest.de).
Die Apache-Konfiguration spiegelt dies auch wider:
<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>Wie ich bereits erw?hnt habe, scheint die Benutzerauthentifizierung so zu funktionieren (
client(自己的票)
> web 服務(wù)(自己的票) > ipa server
). Andernfalls gibt der Apache-Server meinen LDAP/Kerberos-Benutzernamen nicht zurück. Oder übersehe ich hier etwas Wichtiges? Gibt es eine andere M?glichkeit, diese Authentifizierung durchzusetzen?
Ausgabe: <?php print_r($_SERVER) ?>
(abgefangen)
[GSS_MECH] => Negotiate/krb5 [GSS_NAME] => test@EXAMPLETEST.DE [REMOTE_USER] => test [AUTH_TYPE] => Negotiate [PHP_AUTH_USER] => test
確保您的 Web 服務(wù)器具有正確 Kerberos 票證。
通常,Kerberos 身份驗證僅傳輸僅對該服務(wù)器有效的票證,而不是一攬子“所有”票證。當(dāng)客戶端對您的 web 應(yīng)用進(jìn)行身份驗證時,您獲得的只是 HTTP/webapp.example.tld
的票證,并且您無法真正使用它代表用戶訪問 LDAP。
如果您需要代表用戶訪問 LDAP,則有以下幾種選擇:
網(wǎng)絡(luò)應(yīng)用程序可以擁有自己的 LDAP 目錄憑據(jù)。這可能是最簡單的方法。 Web 應(yīng)用程序可以使用標(biāo)準(zhǔn)密碼綁定,也可以使用從密鑰表獲取的自己的票證進(jìn)行 Kerberos (SASL) 綁定。
LDAP 還支持“模擬”,即 Web 應(yīng)用程序?qū)⑹褂米约旱膽{據(jù)進(jìn)行身份驗證,但還指定一個“授權(quán) ID”(authzid) 來確定您將獲得哪個帳戶的權(quán)限。
例如,如果您以“webapp”身份進(jìn)行身份驗證,但指定了 authzid“myuser”(并且如果 LDAP 服務(wù)器允許),那么您將獲得“myuser”通常所擁有的權(quán)限有 – 而不是“webapp”的那些。
Web 應(yīng)用程序的 HTTP 協(xié)商 (SPNEGO) 身份驗證可以啟用“委托”。委派確實將主krbtgt
票證傳輸?shù)絎eb服務(wù)器,然后服務(wù)器會將其放入臨時票證緩存中并可供您的Web應(yīng)用程序環(huán)境使用。
但是,委托有一些問題:
這會使每個 HTTP 請求變慢,因為客戶端必須請求帶有“轉(zhuǎn)發(fā)”標(biāo)志的新 krbtgt
票證(除非 Web 服務(wù)器可以使用例如 cookie 來避免請求協(xié)商身份驗證)用于進(jìn)一步的請求,例如帶有“會話”模式的 mod_auth_gssapi)。
它要求 Web 應(yīng)用程序高度可信,因為它將為每個訪問它的用戶(包括管理員)存儲通配符票證 - 即使 Web 應(yīng)用程序本身被信任不會濫用它們,它們?nèi)匀豢赡鼙桓`取服務(wù)器。
大多數(shù)使用 Kerberos 的 API(包括 ldap_sasl_bind())都期望 KRB5CCNAME
環(huán)境變量指向票證緩存。但環(huán)境變量是進(jìn)程范圍的,因此只要 PHP 重用同一進(jìn)程,它們就可能會在不相關(guān)的請求中泄漏(或者更糟糕的是,如果您使用 mod_php 在 Apache 進(jìn)程內(nèi)運行 web 應(yīng)用程序)。
在 AD 中,這具體稱為“無約束委派”,因為 AD 引入了其他變體。
網(wǎng)絡(luò)應(yīng)用程序可以使用 S4U2Proxy 又名“約束委派”來代表用戶創(chuàng)建票證,以獲取某些有限的服務(wù)集(例如,F(xiàn)reeIPA 可以將其限制為僅訪問 ldap/foo.example.com
)。
這有點復(fù)雜(PHP 沒有這方面的 API - 您可能需要使用正確的標(biāo)志生成 kinit
),并且仍然存在與 KRB5CCNAME 跨請求泄漏相同的潛在問題。
對于常規(guī) Kerberos 身份驗證,用法如下所示:
ldap_sasl_bind($conn, null, null, "GSSAPI");
僅此而已。 GSSAPI SASL 機(jī)制期望環(huán)境已經(jīng)具有可用的 Kerberos 票證(例如通過 $KRB5CCNAME 或通過 gss-proxy),并且它將使用在那里找到的任何票證進(jìn)行身份驗證。
如果您想使用模擬(假設(shè)在 LDAP 服務(wù)器中設(shè)置),則必須指定 authz_id:
ldap_sasl_bind($conn, null, null, "GSSAPI", null, null, $theuser);
大多數(shù) ldap_*()
PHP 函數(shù)都是 C libldap 庫的直接包裝器,因此其文檔可作為部分參考。
看來您的示例已經(jīng)指定了用戶的確切 DN,因此似乎不需要通過 mail
進(jìn)行額外過濾 - 只需在讀取郵件時使用 objectClass=*
特定的DN。另外,當(dāng)您想要讀取特定 DN 時,請使用 ldap_read() 進(jìn)行“基本”搜索而不是子樹搜索。
不,事情不是這樣的。您的用戶名(即客戶端 Kerberos 主體)存儲在客戶端票證中,因此 Web 服務(wù)器在解密票證后立即知道它,而無需與 IPA 對話。