Příručka:SessionManager a AuthManager
SessionManager a AuthManager jsou dva rámce související s autentizací představené v MediaWiki 1.27 , které mají nahradit "může být jen jeden!" povaha AuthPlugin (předchozí autentizační systém), nemožnost provádět federované přihlášení (např. "přihlásit se svým účtem Google") bez použití různých háčků k prolomení zaměření MediaWiki na ověřování založeném na heslech a nemožnost provádět správu relací s čímkoli jiným než soubory cookie, aniž byste znovu použili různé háčky k prolomení závislosti MediaWiki na relacích založených na souborech cookie PHP.
Co dělají?
SessionManager se zabývá přijetím příchozího požadavku a jeho spojením s uživatelskou relací, tj. skutečností, že požadavek pochází od přihlášeného uživatele (nebo ne) a všech dat, která by měla přetrvávat v požadavcích, jako je PHP $_SESSION
.
Obvykle to znamená soubory cookie obsahující "klíč relace" a ID a token uživatele, ale stejně snadno by to mohlo být založeno na přihlašovacích údajích v záhlaví OAuth nebo TLS klientském certifikátu.
AuthManager se zabývá přihlašováním poskytnutím přihlašovacích údajů do Special:UserLogin nebo podobných a vytvářením účtů s novými přihlašovacími údaji. To zahrnuje obvyklou formu uživatelského jména a hesla, ale také mechanismy, jako je přihlášení přes Google, Facebook nebo jinou ověřovací službu třetí strany. Vícefaktorové ověřování a další kontroly doby přihlášení, jako je resetování hesla, CAPTCHA a tak dále.
Jak je mohu použít?
Jako správce systému
Dostupní poskytovatelé relací se konfigurují pomocí $wgSessionProviders
.
Podrobnosti naleznete v dokumentaci tohoto globálního a jednotlivých poskytovatelů relací.
Dostupní poskytovatelé ověřování se konfigurují pomocí $wgAuthManagerConfig
.
Podrobnosti naleznete v dokumentaci tohoto globálního a jednotlivých poskytovatelů autentizace.
Aby AuthManager zvládl operace, kdy by byl uživatel tradičně požádán o zadání svého aktuálního hesla pro potvrzení, místo toho vyžaduje, aby se uživatel brzy aktivně přihlásil během aktuální relace.
Chcete-li nakonfigurovat, co přesně znamená "brzy", použijte $wgReauthenticateTime
k nastavení časových limitů pro každou operaci.
Chcete-li zjistit, co se stane, když uživatel používá něco jako OAuth, kde je každý požadavek individuálně ověřován a "přihlášení" není možné, použijte $wgAllowSecuritySensitiveOperationIfCannotReauthenticate
.
Jako spotřebitel
Relace
Pro přístup k aktuální relaci z vašeho kódu je nejpřímějším mechanismem použití metody getSession()
na vašem objektu WebRequest
.
Výsledný objekt MediaWiki\Session\Session
má metody pro přístup k datům, ke kterým jste v minulosti přistupovali pomocí $webRequest->getSessionData()
a ->setSessionData()
nebo přímým přístupem $_SESSION
.
Chcete-li otestovat, zda je aktuálně aktivní relace tam, kde byste dříve používali kód jako session_id() !== ''
, načtěte objekt Session a použijte jeho metodu ->isPersistent()
.
Chcete-li zajistit, aby byla relace trvalá, načtěte ji a použijte její metodu ->persist()
namísto použití wfSetupSession()
.
Pokud potřebujete přistupovat k datům relace v jiném kontextu, než je požadavek klienta, např. pokud jste uložili ID relace pro spuštění úlohy na pozadí a potřebujete aktualizovat stav v datech relace, použijte MediaWiki\Session\SessionManager::singleton()->getSessionById()
.
Ověřování
Pokud provádíte akci citlivou na zabezpečení, která by tradičně vyžadovala heslo uživatele pro ověření, použijte MediaWiki\Auth\AuthManager::singleton()->securitySensitiveOperationStatus()
ke kontrole, zda se uživatel dostatečně nedávno autentizoval, a v případě potřeby jej přesměrujte přes Special:UserLogin, aby se znovu autentizoval.
SpecialPage
to zvládne za vás, pokud vrátíte non-false z SpecialPage::getLoginSecurityLevel()
.
Kromě toho většina "spotřebitelských" kódů nebude muset komunikovat přímo s AuthManager, protože byste opravdu neměli implementovat svůj vlastní postup ověřování.
Chcete-li zjistit, zda je uživatel přihlášen, použijte obvyklé metody, jako je getUser()
na IContextSource
.
Chcete-li zjistit, zda je uživatel ověřen, nechte jej přihlásit se obvyklou metodou.
Ale pokud opravdu trváte na tom: Autentizace v AuthManager je vícestupňový proces, který probíhá asi takto:
- Zavolejte
$authManager->canAuthenticateNow()
a zjistěte, zda je ověření vůbec možné. - Zavolejte
$authManager->getAuthenticationRequests( AuthManager::ACTION_LOGIN )
, abyste zjistili, které podtřídy AuthenticationRequest jsou potřeba, převeďte je na pole formuláře a prezentujte je uživateli. - Jakmile uživatel odešle formulář, použijte
AuthenticationRequest::loadRequestsFromSubmission()
k naplnění požadavků daty a předejte je$authManager->beginAuthentication()
. - Proveďte akci v závislosti na stavu AuthenticationResponse:
- Pro stavové uživatelské rozhraní převeďte potřebné AuthenticationRequests na pole formuláře, prezentujte je uživateli a při odeslání použijte
AuthenticationRequest::loadRequestsFromSubmission()
k naplnění nových požadavků daty a předejte je$authManager->continueAuthentication()
a zpracujte novou odpověď. - Pro stav REDIRECT přesměrujte uživatele na zadanou adresu URL. Nakonec by měl být uživatel přesměrován zpět a v tomto okamžiku by měly být potřebné požadavky AuthenticationRequest naplněny daty a předány
$authManager->continueAuthentication()
. - Pro stav PASS bylo ověření úspěšné.
- U stavu RESTART bylo ověření pomocí služby třetí strany úspěšné, ale tyto přihlašovací údaje nejsou přidruženy k místnímu účtu. Považujte to za UI nebo FAIL.
- U stavu FAIL se ověření nezdařilo. Odpověď může obsahovat další AuthenticationRequest, který může být předán do
$authManager->beginAuthentication()
nebo$authManager->beginAccountCreation()
, aby se zachoval stav.
- Pro stavové uživatelské rozhraní převeďte potřebné AuthenticationRequests na pole formuláře, prezentujte je uživateli a při odeslání použijte
Procesy pro vytvoření účtu a propojení přihlašovacích údajů třetích stran jsou podobné.
Jako poskytovatel
Pokud píšete kód, který bude poskytovat nové funkce na SessionManager nebo AuthManager, musíte se nejprve rozhodnout, jaký druh věcí poskytujete:
- Pokud implementujete nový způsob, jak vzít WebRequest a určit z něj ověřeného uživatele a data relace, chcete implementovat
MediaWiki\Session\SessionProvider
.- Pokud děláte něco, co vypadá jako přihlášení, SessionProvider není to, co chcete. Pravděpodobně budete chtít místo toho PrimaryAuthenticationProvider.
- If you want to generically add additional checks to the process of getting a Session from a WebRequest, you will likely want to look at the SessionMetadata and SessionCheckInfo hooks. První umožňuje přidat další metadata, která mají být uložena s relací, zatímco druhá umožňuje podívat se na metadata při načítání relace a v případě potřeby vetovat její použití.
- Pokud implementujete nový způsob přihlašování, chcete implementovat
MediaWiki\Auth\PrimaryAuthenticationProvider
.- Pokud vám nejde ani tak o způsob přihlášení, jako o nový způsob, jak jen "být" přihlášený, jako jsou klientské certifikáty OAuth nebo TLS, toto nechcete. Pravděpodobně budete místo toho chtít SessionProvider.
- Pokud implementujete nějakou novou kontrolu, kterou musí někdo projít, než se bude moci přihlásit, jako je CAPTCHA, chcete implementovat
MediaWiki\Auth\PreAuthenticationProvider
. - Pokud implementujete něco, co by se mělo stát po přihlášení, včetně testování druhého faktoru, chcete implementovat
MediaWiki\Auth\SecondaryAuthenticationProvider
.
Ve všech případech jsou poskytovatelé konstruováni pomocí ObjectFactory
od $wgSessionProviders
nebo $wgAuthManagerAutoConfig
a pak mají závislosti vložené metodami setter.
SessionProvider
Dokumentace třídy: MediaWiki\Session\SessionProvider
V zásadě existují tři typy poskytovatelů relací na základě dvou schopností:
- Možnost uložit libovolné náhodně vygenerované ID relace oproti ID založenému na vlastnostech požadavku, které nelze změnit.
- Schopnost být spojen s libovolným uživatelem, který se přihlásí, oproti tomu, že máte uživatele, který je vnitřně spojen s požadavkem.
- Tato posledně jmenovaná vlastnost je někdy označována jako vytváření relace "proměnlivé" versus "neměnné".
Výsledné tři typy jsou:
- Poskytovatelé, kteří mohou uložit libovolné náhodně vygenerované ID relace a mohou být také spojeni s libovolným uživatelem. Typickým příkladem jsou tradiční relace založené na souborech cookie.
- Není nutné, aby poskytovatel skutečně dělal cokoli pro záchranu identity uživatele. Pokud je poskytnuto ID relace, lze uživatele určit z uložených metadat.
- Poskytovatelé, kteří mají ID uživatele a relace vnitřně spojené s požadavkem. Dobrými příklady jsou klientské certifikáty OAuth a TLS: hlavičky OAuth nebo klientský certifikát TLS jsou spojeny s konkrétním uživatelem a nemůžete je jen libovolně změnit tak, aby byly přidruženy k jinému uživateli.
- Poskytovatelé, kteří mají uživatele vnitřně spojeného s požadavkem, ale mohou uložit libovolné náhodně vygenerované ID relace. Příkladem může být autentizace HTTP Digest pomocí pole "opaque" (neprůhledné) k uložení ID relace.
- Často můžete použít metodu s vnitřním uživatelem a bez možnosti uložit náhodně vygenerovaná ID relací a použít cookie, abyste mu tuto možnost dali. Část cookie takového poskytovatele implementuje základní třída
MediaWiki\Session\ImmutableSessionProviderWithCookie
.
- Často můžete použít metodu s vnitřním uživatelem a bez možnosti uložit náhodně vygenerovaná ID relací a použít cookie, abyste mu tuto možnost dali. Část cookie takového poskytovatele implementuje základní třída
Je také možné mít poskytovatele se schopností být přidružen k libovolnému uživateli, ale postrádající možnost uložit náhodně vygenerované ID relace. Zdá se však, že to nedává smysl.
A session provider "provides" sessions by returning a MediaWiki\Session\SessionInfo
object from either provideSessionInfo()
(for the session associated with a WebRequest) or newSessionInfo()
(for a new session not yet associated with any WebRequest).
The properties of the SessionInfo are:
- The priority of the SessionInfo: if by some chance multiple providers find session data in the same request, the one with the highest priority is used. If there is a tie, SessionManager will throw an error. Generally a provider will either always use SessionInfo::MAX_PRIORITY (i.e. "you must use this SessionInfo") or will take the desired priority as a parameter to its constructor.
- ID relace. It's ok for a provider to provide a SessionInfo without providing an ID if it does identify a user.
- Zda požadavek identifikuje uživatele a zda je tento uživatel ověřen nebo jen pojmenován. Použití relací založených na souborech cookie jako příklad
- "No user" results when the UserID or UserName cookie isn't present in the request. Uživatel bude určen z uložených metadat relace.
- "Unauthenticated user" results when the UserID or UserName cookie is present, but the "Token" cookie is missing. Jakékoli ID nebo jméno uživatele je veřejně dostupné, takže bez tokenu nemůžeme vědět, že se nejedná o pokus o falšování.
- To se stále vyplatí, protože můžeme zkontrolovat, zda uložená metadata relace identifikují stejného uživatele, abychom zabránili někomu v použití ID relace, jehož platnost vypršela a bylo přiděleno jinému uživateli.
- "Authenticated user" results when the UserID or UserName cookie is present and the "Token" cookie is also present, and
hash_equals( $user->getToken(), $cookieToken )
returnstrue
. Protože token má být tajný, můžeme předpokládat, že správný token znamená, že se jedná o známého uživatele.- Tokeny, které přicházejí z WebRequest, musí být vždy zkontrolovány pomocí
hash_equals
, aby se zabránilo útokům načasování.
- Tokeny, které přicházejí z WebRequest, musí být vždy zkontrolovány pomocí
- Neexistuje žádný případ, kdy by byly přítomny soubory cookie UserID nebo UserName a cookie "Token", ale
hash_equals( $user->getToken(), $cookieToken )
vrátí hodnotu false. If this happens, the provider must not provide any SessionInfo.
- Whether various bits were actually found in the WebRequest: the session ID, the user's token, and the forceHTTPS flag.
- Jakákoli další metadata, která chce poskytovatel přiřadit k relaci. To je často užitečné, pokud poskytovatel kromě ověřování provádí autorizaci (např. udělení OAuth).
Poskytovatel relace je také zodpovědný za "přetrvání" relace na WebResponse, což se provádí při volání persistSession()
.
Pokud má poskytovatel možnost uložit náhodně vygenerovaná ID relací, učiní tak zde.
If it has the ability to independently save the user identity, it should always save the user's ID or name but must only save the user's token if the session's ->shouldRememberUser()
method returns true.
For proper caching behavior, the session provider needs to use getVaryHeaders()
and getVaryCookies()
to indicate which request headers and cookies it uses to determine the SessionInfo.
Potřebuje také poskytovat zprávy k identifikaci svých relací v chybových zprávách a poskytovat nápovědu, proč relace nepřetrvávají, když by měly (např. že prohlížeč je nastaven tak, aby odmítal soubory cookie).
PreAuthenticationProvider
Dokumentace třídy: MediaWiki\Auth\PreAuthenticationProvider, MediaWiki\Auth\AbstractPreAuthenticationProvider
Poskytovatel "předběžné" autentizace může poskytnout pole pro přihlašovací formulář nebo formulář pro vytvoření účtu a provést kontroly přihlášení nebo pokusu o vytvoření účtu předtím, než dojde ke skutečnému ověření. Může například omezit pokusy o přihlášení podle IP adresy nebo zobrazit CAPTCHA, kterou je nutné vyřešit, aby bylo možné vytvořit účet.
PrimaryAuthenticationProvider
Dokumentace třídy: MediaWiki\Auth\PrimaryAuthenticationProvider, MediaWiki\Auth\AbstractPrimaryAuthenticationProvider
"Primární" poskytovatel autentizace je zodpovědný za skutečné ověření uživatele:
- Převezme vstup z přihlašovacího formuláře, určí, který uživatel se pokouší přihlásit, a skutečně tohoto uživatele ověří.
- Zajistí toho, že vytvářený uživatel se bude moci přihlásit později.
- Testuje, zda uživatelské jméno již existuje v ověřovacím backendovém úložišti.
- Změna ověřovacích dat přidružených k existujícímu uživateli nebo přidání a odebrání přidružení k účtům poskytovatelů ověřování třetích stran.
AuthManager may be configured to use multiple primary authentication providers. On the initial form submission each primary provider in turn is tried, and if it returns an ABSTAIN result the next in line is tried until either one returns a non-ABSTAIN response or it runs out of providers (in which case it generates a FAIL).
The authentication process for a provider is also multi-step: non-ABSTAIN responses include the usual PASS and FAIL, but also UI to present an additional input form for the user to fill out and REDIRECT to send the browser to some third party which should eventually redirect back to continue the authentication process.
SecondaryAuthenticationProvider
Dokumentace třídy: MediaWiki\Auth\SecondaryAuthenticationProvider, MediaWiki\Auth\AbstractSecondaryAuthenticationProvider
"Sekundární" poskytovatel autentizace je volán poté, co byl uživatel ověřen "primárním". Může například vyžadovat druhý faktor pro vícefaktorovou autentizaci, vyzvat uživatele ke změně hesla nebo zkontrolovat, zda uživatel není blokován. Sekundární poskytovatelé jsou také voláni při vytváření účtu, aby mohli dělat úkony, jako je výzva k nastavení vícefaktorového ověřování.
AuthManager may be configured with multiple secondary authentication providers, in which case all are run and must PASS or ABSTAIN for the authentication process to succeed. Like primary providers, they may respond with UI and REDIRECT to interact with the user.
Komunikace mezi poskytovateli autentizace
AuthManager provides support for communication between provider modules during the authentication process.
Například primární poskytovatelé autentizace na základě hesla, kteří mají koncept vypršení platnosti hesla, mohou zavolat $this->getManager()->setAuthenticationSessionData( 'reset-pass', $data )
, což způsobí, že sekundární poskytovatel autentizace MediaWiki\Auth\ResetPasswordSecondaryAuthenticationProvider
vyzve uživatele ke změně hesla.
Je na každém poskytovateli, aby zdokumentoval, jaké "klíče" autentizačních dat používá a jaká data potřebuje ke své práci poskytnout.
Související odkazy
- Manual:SessionManager and AuthManager/Adding fields to the registration form
- Manual:SessionManager and AuthManager/Linked accounts
- Manual:SessionManager and AuthManager/Updating tips
- Manual:SessionManager and AuthManager/Troubleshooting
- Manual:SessionManager and AuthManager/SessionProvider examples
- Spustit úlohu: T89459 a originální RFC.
Správce kódu
- Spravováno MediaWiki Platform Team.
- Živý chat (IRC): #mediawiki-core připojit se
- Nástroj pro sledování problémů: Phabricator mediawiki-auth (nahlášení problému)