2012-07-16 11 views
10

Moim celem jest posiadanie unikalnej soli dla każdego użytkownika, a nie tylko używanie Configure::read('Security.salt') dla każdego użytkownika.CakePHP 2: Nadpisanie metody "hasła" AuthComponent

Wiem, że CakePHP 2.x nie powoduje już automatycznego haszowania haseł. To pozwala mi wykonywać walidację modelu na hasłach, co jest bardzo miłe. Jednak nie widzę sposobu, aby przesłonić metodę "password" AuthComponent. Więc nawet jeśli mogę kontrolować, jak hasła są mieszane przed ich zapisaniem w bazie danych, nie mogę kontrolować, jak hasła są mieszane podczas wykonywania rzeczywistego logowania. Z książki kucharskiej:

Nie trzeba hash hasła przed wywołaniem $this->Auth->login().

Co mogę zrobić, aby $this->Auth->login() użyć niestandardowej metody haszowania hasła?

Dzięki.

AKTUALIZACJA: Skończyłem z odpowiedzią dr Hannibal Lecter (tworzenie niestandardowego obiektu uwierzytelniania). Oto jak to zrobić:

Stary kod:

$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'email'))); 

Nowy kod (zmiana "Form" do "klienta"):

$this->Auth->authenticate = array('Custom' => array('fields' => array('username' => 'email'))); 

Utwórz „app/Controller/Component/Auth/CustomAuthenticate.php "i sprawiają, że wygląda tak:

<?php 
App::uses('FormAuthenticate', 'Controller/Component/Auth'); 

class CustomAuthenticate extends FormAuthenticate { 
} 

Skopiuj "_findUser" i "_password" metody z" lib/ciasto/Controller/Com ponent/Auth/BaseAuthenticate.php "i wklej je do klasy" CustomAuthenticate ". Następnie zrób dwa następujące modyfikacje "_findUser" metody:

  1. usunąć tę linię od "warunków $" tablicy: $model . '.' . $fields['password'] => $this->_password($password),

  2. Zmień if (empty($result) || empty($result[$model])) { do if (empty($result) || empty($result[$model]) || $result[$model][$fields['password']] != $this->_password($password, $result[$model]['id'])) {

następnie dokonać następujące dwie modyfikacje metody "_password":

  1. Tworzenie parametru „$ id” zmieniając protected function _password($password) { do protected function _password($password, $id) {

  2. zaktualizować wartość soli zmieniając return Security::hash($password, null, true); do return Security::hash($password, null, Configure::read('Security.salt') . $id);

Wreszcie, należy zaktualizować wszystkie wystąpienia AuthComponent::password używać Security::hash z tą samą logiką, jak powyżej.

Odpowiedz

4

Prawdopodobnie można utworzyć custom auth object i zahaczyć hasło, jak tylko chcesz. Spójrz na existing auth objects, aby uzyskać ogólne informacje o tym, jak działają.

+0

To zadziałało! Zaktualizowałem swoje pytanie za pomocą odpowiedniego kodu. Dzięki! – Nick

1

Czy myślisz, że nie używasz funkcji Auth-> login(), ale używasz kodu z aktualnej implementacji w swoim modelu? (http://api20.cakephp.org/view_source/auth-component#line-506) Możesz przepisać to w zależności od potrzeb.

+0

Nie jestem pewien, jak to zrobię i nie wydaje mi się to bardzo przyjazne dla programistów. Posiadanie unikalnej soli dla każdego użytkownika zdecydowanie nie jest niezwykłym celem. Czy masz przykładowy kod? Tak czy inaczej, doceniam twój czas. – Nick

1

Dla każdego, kto chce uzyskać więcej informacji o tym, dlaczego solenie każdego hasła jest właściwą metodą na hash (przykłady w kodzie), odwiedź tutaj: http://crackstation.net/hashing-security.htm.

Być może nieznaczne ulepszenie kodu tutaj zamieszczonego to skorzystanie z porady artykułu, do którego właśnie się przyłączyłem i generowanie "nowej losowej soli" ... "za każdym razem, gdy użytkownik tworzy konto lub zmienia hasło . "

W przedstawionej tutaj implementacji zastosowano kombinację oryginalnej statycznej soli Auth i jej identyfikatora użytkownika jako soli, co oznacza, że ​​ta sama sól zostanie ponownie użyta dla każdego użytkownika po zmianie hasła. Jeśli więc chcesz zastosować się do zaleceń tego przewodnika po hashowaniu, musisz wygenerować nową losową sól za każdym razem, gdy użytkownik tworzy/zmienia swoje hasło i musi przechowywać tę unikalną sól w tabeli użytkowników wraz z hashowanym hasłem.

Można używać ich losowy generator Sól:

define("PBKDF2_SALT_BYTES", 24); 
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM)); 

i umownie, należy go przechowywać w tabeli użytkowników w nowym polu o nazwie „sól”. Ponieważ kod daje już identyfikator użytkownika, zawsze możesz zapisać/wyszukać sól w razie potrzeby.

W artykule wspomniano także o "Slow Hash Functions" za pomocą techniki zwanej "key stretching" i jak zaimplementować przy użyciu standardowego algorytmu takiego jak PBKDF2 lub bcrypt. Udostępniono przykłady kodu PHP, które można skopiować i wkleić do niestandardowej implementacji Auth w celu zwiększenia bezpieczeństwa.

CakePHP deweloper Mark Story opublikował wpis na blogu na temat implement bcrypt in CakePHP's Auth

W sekcji komentarzy, Mark Story skomentował, że CakePHP 2.3 będzie miał jakieś nowe wbudowane funkcje do generowania mieszań bcrypt.

0

Atleast w ciastku 2.3 jest już używana sól unikalna, nawet jeśli sól w twojej wartości konfiguracyjnej jest zawsze taka sama. Nie jestem pewien, czy to samo dotyczy starszych wersji.

Można również po prostu zmienić sól w swojej funkcji beforeSave() w modelu użytkownika za pomocą polecenia Configure :: write ("Security.salt", $ superAwesomeUserSpecificSalt);