Integrering av tvåfaktorautentisering med CodeIgniter

Med den senaste strängen av högprofessionella inbrott (hackar) hos Sony och andra företag är det dags att du tog en titt på säkerheten på din webbplats. Tvåfaktorsautentisering är ett steg i rätt riktning för att säkra din webbplats från angripare. I denna handledning tar vi en titt på att implementera detta i vår CodeIgniter-applikation.


Vad är tvåfaktorautentisering?

Tvåfaktorsautentisering kräver att användarna använder något de vet, till exempel ett användarnamn och lösenord, och något de har, som en telefon, för att logga in.

På senare tid har företag som Google och Facebook rullat ut tvåfaktorsautentisering för sina användare. Andra tjänster, som MailChimp, använder alternativa former för tvåfaktorsautentisering för att hjälpa till att förhindra attacker. Men fortfarande, vad är specifikt tvåfaktorsautentisering?

Tvåfaktorsautentisering är ett sätt att bevisa din identitet baserat på ditt användarnamn och lösenord samt en fysisk enhet som du kan bära med dig.


Duos mobilapplikation stöder pushanmälan för autentisering!

Det gör det mycket svårare för skurkar att stjäla din identitet, eftersom de behöver tillgång till din telefon eller maskinvara token - inte bara dina inloggningsuppgifter.

Lycklig för dig, Duo Security erbjuder en gratis tvåfaktorservice som är idealisk för alla som vill skydda sin webbplats.

Duo är inte bara gratis, men den är full av funktioner. De låter dig autentisera på olika sätt, inklusive:

  • Telefonkodsautentisering
  • SMS-baserade tokens
  • Mobil app token generator
  • Push-baserad autentisering
  • Hårdvara tokens tillgängliga för köp

Steg 1: Inställning

Setup CodeIgniter

Om du inte har arbetat med CodeIgniter tidigare rekommenderar jag starkt att du kolla in codecngniter från scratch-serien först.

Denna handledning bygger på Easy Authentication med CodeIgniter handledning. Denna handledning blir mycket lättare för dig att förstå om du slutför den tidigare handledningen innan du fortsätter. Vi kommer att använda filerna från den handledningen som utgångspunkt.

Kontrollera att din config / autoload.php har följande hjälpare laddats.

$ autoload ['hjälper'] = array ('url', 'form');

Skapa ett konto

Gå över till Duosäkerhet och registrera dig för ett konto.

De erbjuder en gratis plan för open source-projekt, och för webbplatser med mindre än 10 Duo-användare (En Duo-användare är någon som använder tvåfaktors autentisering för att logga in).

Skapa en integration

Efter registrering måste du logga in på Duo och skapa en integration. När du är inloggad, klicka på integrationer på sidopanelen för att dra upp integrationssidan. Därifrån klickar du på knappen "Ny integration".

Se till att integrationen du skapar är en webb-SDK-integration. Det här låter dig använda deras PHP API med CodeIgniter.

Integrationsnamnet används endast på Duos hemsida. Det här är bara ett sätt för dig att identifiera din integration. Duo har en startguide som förklarar hur man skapar en integration.

Ladda ner webb-SDK

Förutom att konfigurera en integration måste du ladda ner webb-SDK.

Det finns två delar av SDK som vi behöver: En PHP-fil (duo_web.php) och en JavaScript-fil. Observera att JavaScript har ett jQuery-beroende och det medföljande JavaScript levereras med jQuery.

Vi använder den medföljande JavaScript, men notera att om du inte är, måste jQuery laddas innan JavaScript tillhandahålls av Duo. För mer information om webb-SDK och hur det fungerar, se dokumentationen på http://www.duosecurity.com/docs/duoweb


Steg 2: Modifieringar för säkerhet

Efter att du har slutfört Easy Authentication med CodeIgniter handledning, borde du ha ett grundläggande inloggningssystem på plats.

Bättre Hashing

Som ett första steg lägger vi till en stark hashfunktion i databasen. Openwall har ett trevligt PHP hashing bibliotek som implementerar bcrypt. Den senaste versionen av phpass är 0,3 vid tidpunkten för denna artikel.

Gå vidare och ladda ner phpass från deras hemsida: http://openwall.com/phpass/. När du har hämtat och arkiverat mappen måste du placera det i mappen Bibliotek.

Vi behöver nu skapa vår egen biblioteksfil som ett gränssnitt till phpass. Skapa en ny biblioteksfil med namnet password.php. Vårt bibliotek har två funktioner:

  • en hash-funktion för att återhämta de gamla lösenorden
  • en check_password funktion för att jämföra hashes med plaintext lösenord.
require_once ( 'phpass-0,3 / PasswordHash.php'); klass lösenord var $ hasher; funktionen __construct () // 8 är hashstyrkan. Ett större värde kan användas för extra säkerhet. // TRUE gör lösenordet bärbart. FALSE är mycket säkrare. $ this-> hasher = nytt PasswordHash (8, TRUE);  funktion hash ($ pass) returnera $ this-> hasher-> HashPassword ($ pass);  funktion check_password ($ pass, $ hash) return $ this-> hasher-> CheckPassword ($ pass, $ hash); 

De require_once () uttalande säkerställer att vi kommer att kunna använda PasswordHash klass från phpass.

PasswordHash tar två argument i sin konstruktör:

  • ett tal som indikerar hashstyrka
  • en booleska om lösenordet ska vara bärbart.

I det här fallet kommer vi att göra våra lösenord bärbara.

Detta betyder i huvudsak att hasen inte är lika stark, men om vi någonsin behöver byta servrar eller flytta databasen, kan vi göra en kopia. Om vi ​​inte använder ett bärbart hashingprogram riskerar vi att alla användare skapar nya lösenord om databasen flyttas.

Notera: Trots att vi implementerar en starkare hashing-funktion, bör du fortfarande kräva att användarna har ett starkt lösenord.

Ändra administratormodellen

 public function verify_user ($ email, $ password) $ q = $ this -> db -> var ('email_address', $ email) -> limit (1) -> get ('users'); om ($ q-> num_rows> 0) $ result = $ q-> row (); $ This-> last> bibliotek (lösenord '); // Se till att hackarna matchar. om ($ this-> password-> check_password ($ lösenord, $ resultat-> lösenord)) return $ result;  returnera false; 

Tidigare valde vi användaren via e-postadressen och det lösenordsordnade lösenordet. Nu drar vi användaren från databasen utifrån e-postadressen. Det innebär att vi måste validera lösenordet innan vi kan återvända användaren.

När vi har dragit användaren från databasen laddar vi lösenordsbiblioteket som vi just skapat och verifierar att det inmatade lösenordet matchar det lösenordsordnade lösenordet.

Om de två lösenorden matchar, fortsätter vi att returnera användaren, annars kommer vi tillbaka falsk.

Var noga med att använda lösenordsbiblioteket för att ha ett nytt lösenord för dig själv. Lösenorden i din databas kommer nu att vara ogiltiga!

Ändra användarbordet

Vi lägger till ett grundläggande behörighetsfält i databasen. Denna behörighet avgör huruvida användaren loggar in med tvåfaktorsautentisering eller ej.

Vi måste lägga till en kolumn i användartabellen för tvåfaktorbehörigheter. Du kan göra det via phpMyAdmin, eller genom att köra följande SQL.

ALTER TABLE-användare lägger till two_factor_permission BOOLEAN NOT NULL;

Ett värde av 1 i kolumnen Tillstånd gör att användaren använder tvåfaktors autentisering.

SQL lägger till en boolesk kolumn till användartabellen. Vi använder det här för att kräva att användarna använder tvåfaktors autentisering, eller att kringgå den.

Om du gjorde det här så borde du se en ny kolumn i användartabellen. Då måste du uppdatera en aktuell post eller lägga in en ny post som anger two_factor_permission till Sann (1).

Om denna kolumn är inställd på falsk (0), kommer användaren att kunna kringgå tvåfaktors autentisering. Detta är idealiskt för användare som inte behöver samma säkerhetsnivå som administratör.


Steg 3: Använda tillståndsinställningen

Vi behöver ett sätt att kringgå sekundär autentisering, samt ett sätt att infoga ett sekundärt autentiseringssteg till inloggningsprocessen.

Bypassing Sekundär autentisering

Först måste vi ha ett sätt att kringgå sekundär autentisering. Det betyder att vi måste inspektera användaren i administratörskontrollen.

 om ($ res! == FALSE) $ _SESSION ['användarnamn'] = $ res-> email_address; om ($ res-> two_factor_permission) $ this -> _ second_auth ($ res-> email_address); lämna tillbaka;  annat $ _SESSION ['logged_in'] = TRUE; omdirigera ( 'Välkommen'); 

Detta kontrollerar om användaren ska vara inloggad med vårt tvåfotsystem.

Om användaren ska använda tvåfaktorsautentisering vill vi att de ska gå till den sekundära autentiseringssidan utan att logga in dem.

Istället för att omdirigera användaren kan vi ringa _second_auth () funktionen och ha det som laddar sidan. "lämna tillbaka"uttalandet undviker att ladda in inloggningsformuläret.

Vi har skapat en ny session variabel inloggad som vi ska använda för att verifiera att användaren är inloggad. Det betyder att vi behöver göra några ändringar i omdirigeringen.

Åtgärda omdirigeringar

Det finns två omdirigeringar som behöver ändras: den första är i administratörens indexfunktion.

om (isset ($ _ SESSION ['logged_in']) && $ _SESSION ['logged_in'] === TRUE) omdirigera ('välkommen'); 

Den andra är i Välkommen kontrollant. Vi måste se till att användaren inte är inloggad före omdirigering.

om (! isset ($ _ SESSION ['logged_in']) || $ _SESSION ['logged_in']! == TRUE) omdirigera ('admin'); 

Infoga sekundär autentisering

Nu behöver vi hantera sekundär autentisering.

I admin / index funktion vi kallar _second_auth (), så låt oss skriva en grundläggande funktion.

 allmän funktion _second_auth ($ användarnamn) echo "Välkommen $ användarnamn, du tittar på en sekundär autentiseringssida."; 

Steg 4: Konstruera vyn

Traditionella autentiseringssystem behandlar loginer som ett enda stegsprocess.

Duo ger oss lite JavaScript och HTML för att injicera mellan de två stegen. Det betyder att vi måste skapa en vy med den obligatoriska koden.

Låt oss skapa en ny vy, kallad second_auth.php i visningar mapp. Vi måste infoga iframe och JavaScript som Duo tillhandahåller för att få det att fungera.

Du borde skapa en sida med den grundläggande HTML-strukturen. Följande kan placeras i kroppen:

  

I en typisk inställning skulle du behålla all din JavaScript i en resursmapp. Här har vi lagt en Medel mapp i rotten på vår webbplats, med en "js'undermapp som innehåller Web SDK JavaScript-filen.

Vår src kommer att se ut som:

src ="resurser / js / Duo-web-v1.js"

Vi måste också lägga till den andra biten av JavaScript.

Vi genererar dessa data från regulatorn inom kort.

Infoga en blankett

Om du följde den tidigare handledningen bör du ha konfigurerat CodeIgniter för att skydda mot CSRF.

Eftersom JavaScript kommer att skicka data till vår controller, kommer CodeIgniter leta efter CSRF-token. Om vi ​​inte har denna token får vi ett fel.

JavaScript som vi använder kommer att skicka in en blankett med id "duo_form". Allt vi behöver göra är att skapa det.

echo form_open ('admin', array ('id' => "duo_form")); echo form_close ();

Genom att använda formulärklassen kommer CodeIgniter att automatiskt injicera token. När formuläret blir upplagt kommer CodeIgniter att hitta token och låt oss fortsätta.


Steg 5: Förbereda data

Tillbaka i administration controller, vi behöver generera några data i vår _second_auth () fungera.

Värddatorn är API-webbadressen som du fick med när du anmälde dig till Duo. Den här webbadressen ska se ut som om api-xxxxxxxx.duosecurity.com (där "xxxxxxxx" är en unik sträng bundet till ditt Duo-konto).

$ data ['host'] = "api-xxxxxxxx.duosecurity.com";

Kom ihåg att ersätta värden med din specifika webbadress. Ovanstående URL fungerar inte.

Efterhandlingen är den URL som kommer att hantera svaret när användaren har försökt att verifiera med Duo.

Vi skapar en annan funktion i administratörskontrollen för att hantera baksidan. För närvarande namnger vi funktionen process_second_auth ().

 $ data ['post_action'] = base_URL (). "Admin / process_second_auth";

Läser in PHP Web SDK

Se till att du byter namn på "duo_web.php" till "duo.php" för att undvika CodeIgniter-fel.

Om du inte har laddat ner den senaste kopian av duo_web.php kan du hämta den från Duos webb SDK GitHub-sida.

Eftersom webb-SDK kommer som en PHP-klass kan vi byta namn på den till "duo.php"och placera den i vår" program / bibliotek "-mapp.

När du har lagt filen in i bibliotek mapp kan vi ladda den i vår controller.

 allmän funktion _second_auth ($ användarnamn) $ this-> load-> library ('duo'); $ data ['host'] = "api-xxxxxxxx.duosecurity.com"; $ data ['post_action'] = base_URL (). "Admin / process_second_auth"; echo "Welcome $ användarnamn, du tittar på en sekundär autentiseringssida."; 

Genererar den signerade begäran

För att förstå hur man genererar sig_request, du måste förstå vad vi genererar.

De $ akey variabel måste vara minst 40 tecken långt, annars kommer Duo-biblioteket att returnera ett fel!

Duo Web SDK skapar två signerade tokens, en med den hemliga nyckeln de ger dig, en annan med en applikationsnyckel som du gör.

sig_request är en kombination av de två tokensna.

Genom att skapa din egen applikationsnyckel får du ett andra säkerhetslager. En angripare behöver både den hemliga nyckeln från Duo och din personliga applikationsnyckel för att spoofa ett token.

Nu genererar vi "sig_request". Duo kommer att ge dig en integrationsnyckel och hemlig nyckel när du skapar en integration.

Var noga med att ersätta texten nedan med integrationsnyckeln och den hemliga nyckeln som ges till dig. Du måste skapa din egen hemliga nyckel. Det måste vara minst 40 tecken långt och borde vara så slumpmässigt som möjligt.

allmän funktion _second_auth ($ användarnamn) $ this-> load-> library ('duo'); // Duo Integration Key $ ikey = "BYTE MED DIN DUO INTEGRATION KEY"; // Duo Secret Key $ skey = "BYTE MED DIG DUO HÄRLIG NYCKEL"; // Personlig applikationsnyckel $ akey = "CREATE A APPLICATION KEY"; $ data ['host'] = "api-xxxxxxxx.duosecurity.com"; $ data ['post_action'] = base_URL (). "Admin / process_second_auth"; $ data ['sig_request'] = $ this-> duo-> signRequest ($ ikey, $ skey, $ akey, $ användarnamn); echo "Welcome $ användarnamn, du tittar på en sekundär autentiseringssida."; 

duons signRequest () kommer att generera tokens och returnera dem som en sträng att passera till sig_request.

Nu måste vi ladda data till den vy vi skapade tidigare.

allmän funktion _second_auth ($ användarnamn) $ this-> load-> library ('duo'); // Duo Integration Key $ ikey = "BYTE MED DIN DUO INTEGRATION KEY"; // Duo Secret Key $ skey = "BYTE MED DIN DUO SECRET KEY"; // Personlig applikationsnyckel $ akey = "CREATE A APPLICATION KEY"; $ data ['host'] = "api-xxxxxxxx.duosecurity.com"; $ data ['post_action'] = base_URL (). "Admin / process_second_auth"; $ data ['sig_request'] = $ this-> duo-> signRequest ($ ikey, $ skey, $ akey, $ användarnamn); $ this-> load-> view ('second_auth', $ data); 

Om du försöker logga in nu ska du se den här sidan:

Detta är inskrivningsformuläret. Du kan registrera din mobiltelefon här, men vi har inget att behandla sekundär autentisering så det loggar inte in dig.

Om du inte ser någonting alls, se sidkällan för felmeddelanden. Eventuella fel med data kommer att visas i > märka.

Om det står "Access Denied", se till att du har angett integrationen och hemlig nyckeln från Duo Securitys hemsida.


Steg 6: Behandling av sekundär autentisering

Vi har satt upp vår poståtgärd för att vara admin / process_second_auth, så vi behöver skapa en process_second_auth () fungera.

public function process_second_auth () if (isset ($ _ SESSION ['logged_in']) && $ _SESSION ['logged_in'] === TRUE) omdirigera ('välkommen'); 

Eftersom denna funktion kommer att ha sin egen URL måste vi omdirigera inloggade användare.

Vi måste ladda Duo-biblioteket igen för att validera data.

$ This-> last> bibliotek (duo '); // Samma nycklar som används i _second_auth () $ ikey = "BYTE MED DIN DUO INTEGRATION KEY"; $ skey = "BYTE MED DIN DUO SECRET KEY"; $ akey = "BYTE MED DIN ANVÄNDNINGSSYSTEM";

Vi behöver samma $ ikey, $ skey och $ akey från _second_auth () funktion för att validera den upplagda data.

JavaScript inlägg tillbaka a sig_response från Duo-servrarna.

$ sig_response = $ this-> input-> post ('sig_response'); $ username = $ this-> duo-> verifyResponse ($ ikey, $ skey, $ akey, $ sig_response);

En gång har vi dragit sig_response från den upplagda data kör vi den genom verifyResponse () fungera. Detta kommer att returnera NULL om tokens inte matchar, eller ett användarnamn om de är giltiga.

om ($ användarnamn) $ _SESSION ['logged_in'] = TRUE; omdirigera ( 'Välkommen');  annars omdirigera ('admin'); 

Slutligen verifierar vi att ett användarnamn returnerades och slutar logga in genom att ange värdet av $ _SESSION [ 'logged_in'] till sant.

Sammantaget ser funktionen ut så här:

public function process_second_auth () if (isset ($ _ SESSION ['logged_in']) && $ _SESSION ['logged_in'] === TRUE) omdirigera ('välkommen');  $ this-> load-> library ('duo'); // Samma nycklar som används i _second_auth () $ ikey = "BYTE MED DUO'S INTEGRATION KEY"; $ skey = "BYTE MED DUO'S SECRET KEY"; $ akey = "BYTE MED DIN ANVÄNDNINGSSYSTEM"; $ sig_response = $ this-> input-> post ('sig_response'); $ username = $ this-> duo-> verifyResponse ($ ikey, $ skey, $ akey, $ sig_response); om ($ användarnamn) $ _SESSION ['logged_in'] = TRUE; omdirigera ( 'Välkommen');  annars omdirigera ('admin'); 

Nu ska du kunna logga in med tvåfaktors autentisering, fortsätt och prova det!


Slutsats

Förhoppningsvis har du satt upp ditt eget tvåfaktors autentiseringssystem för CodeIgniter!

Vad mer kan du göra? Det finns mycket att göra när det gäller säkerhet, men den största förbättringen skulle spåra användaråtgärder.

Ett bra säkerhetssystem är inte bara säkert: det hjälper dig att identifiera varifrån en sårbarhet kom ifrån. Du bör hålla reda på inloggningsförsök och andra åtgärder som gör det lättare att identifiera attacker.

Tack för att du läser! Om du har problem, lämna ett inlägg i kommentarerna.