I wrote a class AlephBaseAuthenticate that extents BaseAuthenticate which works fine:
<?php
// Authentication against Aleph X-Service
// user and password for x-service see aleph.ini
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
App::uses('IniReader', 'Configure');
Configure::config('default', new IniReader());
class AlephAuthenticate extends BaseAuthenticate {
public function authenticate(CakeRequest $request, CakeResponse $response) {
// Do things for Aleph here.
// Return an array of user + group-id if they could authenticate the user,
// return false if not
// verification = empty works, so we have to check lenght of verification!
$configfile = Configure::read('configfile');
Configure::load($configfile, 'default');
$alephxurl = Configure::read('aleph.xurl');
$xlib = Configure::read('aleph.xlib');
$username = $request->data['Users']['username'];
$password = $request->data['Users']['password'];
$req = $alephxurl . 'library=' . $xlib . '&verification=' . $password . '&op=bor_info&bor_id=' . $username;
$userxml = file_get_contents($req);
$xml = simplexml_load_string($userxml);
$error = $xml->error;
if($error == 'Error retrieving Patron System Key' || strlen($password) == 0){
return FALSE;
} else {
$data['username'] = $xml->z303->{'z303-name'};
$data['group'] = $xml->z303->{'z303-profile-id'};
$data['id'] = $xml->z303->{'z303-id'};
return $data;
}
}
}
In my UserController I added
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'Aleph'
)
)
);
function beforeFilter(){
$this->Auth->allow('index', 'login', 'logout');
}
The problem is: Only in UsersController.php, action "login", I can access this->Auth->user('id'), and, $this->Auth->allow('index', 'login', 'logout') doesn't work at all. Access to every action after login throughs a "You are not authorized to access that location". Looks like authentication doesn't work at all.
Any idea whats wrong here?
Thanks,
Christoph
Related
I have a problem about login multi user in my sistem. The sistem login is not worked as a flowchart below (language is Indonesia):
Flowchart Login Multi User
And the controller code is this:
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Controllers\BaseController;
use App\Models\LoginModel;
/**
*
*/
class Login extends BaseController
{
public function index()
{
helper(['form']);
echo view('formlogin');
}
public function auth()
{
$session = session();
$model = new LoginModel();
$username = $this->request->getVar('username');
$password = $this->request->getVar('password');
$data = $model->where('username', $username)->get()->getRowArray();
//$data = $model->get()->getResultArray();
if ($data) {
//$pass = $data['password'];
$pass = password_hash($data['password'], PASSWORD_DEFAULT);
$verify = password_verify($password, $pass);
if ($verify) {
$session_data = [
'id_login' => $data['id_login'],
'username' => $data['username'],
'password' => $data['password'],
'level' => $data['level'],
'logged_in' => TRUE
];
$session->set($session_data);
if ($level = 'adminsuper') {
return redirect()->to(base_url('/adminsuper'));
}elseif ($level = 'admin') {
return redirect()->to(base_url('/admin'));
}
//return redirect()->to(base_url('/adminsuper'));
}else{
$session->setFlashdata('msg', '<div class="alert alert-danger text-center">Username dan Password Salah</div>');
return redirect()->to(base_url('/login'));
}
}else{
$session->setFlashdata('msg','<div class="alert alert-danger text-center">Pengguna Tidak Terdaftar</div>');
return redirect()->to(base_url('/login'));
}
}
public function logout()
{
$session = session();
$session->destroy();
return redirect()->to(base_url('/login'));
}
}
?>
What should I do, in order to be able to login multi user based on user level?
The level of admin are adminsuper and admin.
this way log in log out is outdatae use jwt(jwt.io) its modern
way login and secure
I'm struggling with a problem. I use the Phalcon framework.
The problem is, the $this->security->checkHash() function always returns false.
What I've checked so far:
Checked the length of the varchar password field (is 255) so the hash should fit perfectly inside the field.
Currently, the code looks like this:
The register function:
public function registerAction()
{
$postData = $this->request->getPost();
/*
* Validation
*/
$validation = new RegistrationValidation();
$validationMessages = $validation->validate($postData);
if (count($validationMessages)) {
// Validation Failed!
foreach ($validationMessages as $message)
$this->flashSession->error( $message);
$this->response->redirect( $_SERVER['HTTP_REFERER'] );
$this->response->send();
} else {
// Check Passwords Match
if($postData['password'] !== $postData['password-repeat']) {
$this->flashSession->error( "Passwords don't match");
$this->response->redirect( $_SERVER['HTTP_REFERER'] );
$this->response->send();
}
}
/**
* Begin registration Process
*/
$user = new Users();
$password = $this->request->getPost('pawword');
$password = $this->security->hash($password);
$user->username = $this->request->getPost('username');
$user->email = $this->request->getPost('email');
$user->register_ip = $_SERVER['REMOTE_ADDR'];
$user->password = $password;
$user->active = 0;
// Store user
$user->save();
$this->view->emailmsg = $this->sendVerificationMail($user->id, $user->email, $user->username);
}
the login function:
public function loginAction()
{
if ($this->request->isPost()) {
$email = $this->request->getPost("email");
$password = $this->request->getPost("password");
var_dump($password);
$user = Users::findFirstByEmail($email);
var_dump($this->security->checkHash( 'edrsvc', '$2y$12$ZERPY2Q3N0hUdG1XSkw5V.DqhYek97IZyrRQwq/UP/X7xO3PiPIpG' ));
var_dump($this->security->checkHash($password, $user->password));
var_dump(password_verify('edrsvc', '$2y$12$ZERPY2Q3N0hUdG1XSkw5V.DqhYek97IZyrRQwq/UP/X7xO3PiPIpG'));
die();
if ($user) {
if ($this->security->checkHash($password, $user->password)) {
var_dump($user);
die();
$this->_registerSession($user);
$this->flash->success(
"Welcome " . $user->name
);
// Forward to the 'invoices' controller if the user is valid
$this->dispatcher->forward(
[
"controller" => "index",
"action" => "index",
]
);
}
} else {
$this->security->hash(rand());
$this->flashSession->error(
'Wrong Email or password Back'
);
}
}
}
You can see those 3 var_dumps, which are actually functioning and not throwing exceptions, but always return false. The password is of course
correct and checked twice.
The workFactor is set to Phalcon's default workFactor.
I am trying to resolve a bug on a client's application, but i can't log in.
So i go to application.dev/metier/login, with application.dev as my virtual host, metier my admin route page and login the page to log in the application.
I complete the form, click on connect, i am getting logged in, redirected to the index page (application.dev/metier/index) but immediately after the redirection i am kicked out to the login page. The url is still application.dev/metier/index, but the i am seeing the login page as i was not authenticated.
I checked session, cleared after redirection.
It is like it's working fine, I am known from database, inserted in session, known as admin, but kicked out no matter what i do. No error, no log. Zend do not enter indexAction().
I can't go to another page due to the routing, and if i try to put my informations in session before access login page, i have an error "too many redirections" (i am in authenticated so go to index, but no i am kicked out, but i am authenticated, but i am kicked out...).
I am on Zend framework 1.12.18, Windows 10, with laragon (Kaspersky as antivirus). I also tried with wamp, and on an Ubuntu VM with xampp, same problem. I tried on another computer, same problem.
It works on the developer who gave me the source code. He gave me the original code and the code with his modification (of application.ini mainly), both give me the "error".
Controller:
public function loginAction() {
try {
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$this->redirect('/metier/index/');
return;
}else{
Zend_Session::regenerateId();
}
$loginForm = new Application_Form_Admin_Login();
$request = $this->getRequest();
if ($request->isPost()) {
if ($loginForm->isValid($request->getPost())) {
if ($this->_process($loginForm->getValues())) {
// We're authenticated! Redirect to the home page
$this->_helper->redirector('index', 'index');
}
} else {
Log::debug('User sent invalid data.', __FILE__, __LINE__);
Log::debug($request->getPost(), __FILE__, __LINE__);
Log::debug('Errors: ', __FILE__, __LINE__);
Log::debug($loginForm->getErrors(), __FILE__, __LINE__);
$this->view->error = Zend_Registry::get('Language')->errors->login->error;
}
}
} catch (Exception $e) {
//$this->view->error = 'Wrong username and/or password';
$this->redirect('/metier/login/');
return;
}
$this->view->form = $loginForm;
}
protected function _process($values) {
if (!trim($values['username']) || !trim($values['password'])) {
$this->view->error = Zend_Registry::get('Language')->errors->login->empty;
return false;
}
// Get our authentication adapter and check credentials
$adapter = $this->_getAuthAdapter();
$adapter->setIdentity($values['username']);
$adapter->setCredential($values['password']);
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
Log::debug('Authentication returned result code: ' . $result->getCode(), __FILE__, __LINE__);
switch ($result->getCode()) {
case Zend_Auth_Result::SUCCESS:
$mdlMetierDep = new Application_Model_DbTable_MetierDepartement();
$user = $adapter->getResultRowObject();
$metDepObj = $mdlMetierDep->fetchRow(array('id_metier = ?' => $user->id_metier, 'id_departement = ?' => $user->id_departement));
if (!$metDepObj) {
$this->view->error = Zend_Registry::get('Language')->errors->login->error;
return $this->_redirect('/metier/login/');
}
$user->Role = Acl::ROLE_ADMIN_METIER;
$user->id_metier_departement = $metDepObj->getIdMetierDepartement();
$user->metier = $metDepObj->findMetier()->toArray();
$user->department = $metDepObj->findDepartement()->toArray();
// to help thwart session fixation/hijacking
// store user object in the session
$authStorage = $auth->getStorage();
$authStorage->write($user);
$this->_redirect('/metier/index/');
break;
case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
default:
$this->view->error = Zend_Registry::get('Language')->errors->login->error;
break;
}
if ($result->isValid()) {
$user = $adapter->getResultRowObject();
//$auth->getStorage()->write($user);
return true;
}
return false;
}
The login and reporting actions (just for informations, zend do not goes in it)
public function indexAction() {
$this->go('reporting');
}
public function reportingAction() {
$this->loadJs(('/scripts/metier/general.js'));
$this->loadCss(('/styles/metier/DataTable.css'));
$this->loadJs(('/scripts/jquery.dataTables.js'));
$this->loadJs(('/scripts/metier/data-table.js'));
}
Init function :
public function init() {
/* Initialize action controller here */
parent::init();
$this->loadCss(('/styles/web/tables2.css'));
$this->loadJs(('/scripts/web/tinyMceConfigs.js'));
$this->language = Zend_Registry::get('Language');
$this->view->language = $this->language;
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$this->storage = $auth->getStorage()->read();
$this->_getLogo();
} else {
$this->view->noLogo = true;
}
//enum field for indicateurs
$this->view->frequence = array('M', 'T', 'S', 'A');
$this->view->sens = array(
'A' => 'Croissant',
'D' => 'Décroissant',
);
$this->view->formulaType = array(
0 => 'rule',
1 => 'min',
2 => 'max',
3 => 'avg');
$this->view->FormulaOperand = array(
0 => '+',
1 => '-',
2 => '/',
3 => '*');
$this->view->tableauTypes = array(Constants::TABLEAU_STRUCTURE_DETAILLE, Constants::TABLEAU_STRUCTURE_COMPTEURS, Constants::TABLEAU_STRUCTURE_GRAPH);
$this->view->operands = array('+', '-', '*', '/');
$this->view->pageTypes = array(
Constants::PAGE_GARDE,
Constants::PAGE_CONTENU,
Constants::PAGE_TABLEAUX,
);
$this->view->HautEtBasTypes = array(
Constants::HEADER => Constants::HEADER,
Constants::FOOTER => Constants::FOOTER,
);
$this->loadCss('styles/forms.css', 'form_css');
$this->view->config = Zend_Registry::get('AppConfig');
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('add-metier', 'json')
->setAutoJsonSerialization(true)
->initContext();
$this->_loggedInUser = Zend_Auth::getInstance()->getIdentity();
ini_set('display_errors', 1);
error_reporting(E_ALL);
}
Classname :
class MetierController extends Reporting_Controller {...}
After debugging, it goes to $this->_redirect('/metier/index') and then kick me out
What could be the problem ?
I have a CakePHP app that I am trying to upgrade from 1.3 to 2.7.5 and I can hit the log in page but when I go to log in, it doesn't do anything, no errors, just basically refreshes the page. I am really confused why this is happening and would greatly appreciate any help I could get. I did post another question about this but deleted it because it did not provide enough of the code to solve the problem. I have included the AppController as well as the Users controller below.
AppController.php
?php
class AppController extends Controller {
var $components = array('Auth', 'Session', 'RequestHandler');
var $uses = array('Tour');
function beforeFilter() {
$this->setLayout();
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'find_home');
$this->Auth->autoRedirect = false;
if ($this->Session->check('Auth.User.userid')) {
$tour = $this->Tour->findByUserid($this->Session->read('Auth.User.userid'));
$user = $this->Auth->user();
$tour = $this->Tour->findByUserid($user['User']['userid']);
$user['Tour'] = $tour['Tour'];
$this->set('user', $user);
}else if (isset($_GET['token'])) {
$tour = $this->Tour->read(null, $_GET['token']);
if ($tour) {
$tour['Tour']['sessionmodified'] = date('Y-m-d H:i:s');
$this->Tour->save($tour);
$this->set('user', $tour);
}
}
}
private function setLayout() {
if (array_key_exists('prefix', $this->params)) {
if ($this->params['prefix'] == 'admin') {
$this->layout = 'admin';
}else if ($this->params['prefix'] == 'teacher') {
$this->layout = 'teacher';
}
}
}
}
?>
UserController.php
function login() {
if (!empty($this->data) && $this->Auth->user()) {
// Delete all old tokens
$this->Tour->recursive = -1;
$this->Tour->deleteAll(array('Tour.userid' => $this->Auth->user('userid')));
// Create a new token
$this->Tour->create();
$this->Tour->save(array('token' => md5(rand()), 'userid' => $this->Auth->user('userid')));
// Update login count
$user = $this->User->read(null, $this->Auth->user('userid'));
$user['User']['logincount']++;
$this->User->saveField('logincount', $user['User']['logincount']);
// Update last login time
$this->User->saveField('lastlogin', date('Y-m-d h:m:s'));
$this->redirect($this->find_home());
}
}
function logout() {
if (!empty($this->data) && $this->Auth->user()) {
// Delete any tours
$this->Tour->recursive = -1;
$this->Tour->deleteAll(array('Tour.userid' => $this->Auth->user('userid')));
}
$this->redirect($this->Auth->logout());
}
function index() {
$this->layout = false;
$this->autoRender = false;
Configure::write('debug', 0);
ini_set('soap.wsdl_cache_enabled', '0');
$server = new SoapServer('http://' . $_SERVER['HTTP_HOST'] . $this->webroot . 'users/wsdl');
$server->setClass('User');
$server->handle();
}
I have a log in form that checks the user email and password through the database, if it matches, it allow the user to log in. The problem is it checks the email that matches any password in the database or the password that matches any emails in the database. I want it to check this specific user email to match his password, not matches any password that exists in database.
Here's my controller that I think I did it wrong:
$loginForm = new Application_Form_UserLogin();
if ($this->getRequest()->isPost('loginForm'))
{
$email_adrress = $this->getRequest()->getParam('email_address');
$password = $this->getRequest()->getParam('password');
/************ Login Form ************/
if ($loginForm->isValid($this->getRequest()->getParams()))
{
$user = $this->_helper->model('Users')->createRow($loginForm->getValues());
$user = $this->_helper->model('Users')->fetchRowByFields(array('email' => $email_adrress, 'hash' => $password));
if($user)
{
Zend_Session::rememberMe(86400 * 14);
Zend_Auth::getInstance()->getStorage()->write($user);
$this->getHelper('redirector')->gotoRoute(array(), 'invite');
return;
}
else {
}
}
}$this->view->loginForm = $loginForm;
My form:
class Application_Form_UserLogin extends Zend_Form
{
public $email, $password, $submit;
public function init()
{
$this->setName('loginForm');
$EmailExists = new Zend_Validate_Db_RecordExists(
array(
'table' => 'users',
'field' => 'email'
)
);
//$EmailExists->setMessage('Invalid email address, please try again. *');
$PasswordExists = new Zend_Validate_Db_RecordExists(
array(
'table' => 'users',
'field' => 'hash'
)
);
$PasswordExists->setMessage('Invalid password, please try again. *');
$this->email = $this->createElement('text', 'email_address')
->setLabel('Email')
->addValidator($EmailExists)
->addValidator('EmailAddress')
->setRequired(true);
$this->password = $this->createElement('text', 'password')
->setLabel('Password')
->addValidator($PasswordExists)
->setRequired(true);
$this->submitButton = $this->createElement('button', 'btn_login')
->setLabel('Login')
->setAttrib('type', 'submit');
$this->addElements(array($this->email, $this->password, $this->submit));
$elementDecorators = array(
'ViewHelper'
);
$this->setElementDecorators($elementDecorators);
}
}
I wouldn't add this login processing as a validator on one of the elements. Instead, I would create an Zend_Auth authentication adapter with your User model, email, and password as constructor arguments. Then, in controller, call Zend_Auth::authenticate($adapter).
Something like:
class Application_Model_AuthAdapter implements Zend_Auth_Adapter_Interface
{
protected $userModel;
protected $email;
protected $pass;
public function __construct($userModel, $email, $pass)
{
$this->userModel = $userModel;
$this->email = $email;
$this->pass = $pass;
}
public function authenticate()
{
$user = $this->userModel->getByEmailAndPassword($this->email, $this->pass);
if ($user){
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user);
} else {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null);
}
}
}
Then in your controller:
public function loginAction()
{
$form = new Application_Form_UserLogin();
if ($this->_request->isPost()) {
if ($form->isValid($this->_request->getPost())) {
$data = $form->getValues();
$email = $data['email'];
$pass = $data['pass'];
$userModel = $this->_helper->model('Users');
$authAdapter = new Application_Model_AuthAdapter($userModel, $email, $pass);
$result = Zend_Auth::getInstance()->authenticate($adapter);
if ($result->isValid()){
// $user= $result->getIdentity(). Use it how you like.
// Redirect someplace
} else {
$this->view->error = 'Invalid login';
}
}
}
$this->view->form = $form;
}
See Zend_Auth reference for more details.
I'm not familiar with the way you're trying to do it. Is the fetchRowByFields method one you have written yourself? If so, it's difficult to help you without seeing the code.
Have you considered using the mechanism provided by Zend Framework to perform authentication against a database?
The Zend Framework official manual contains a brief tutorial on how to implement authentication:
http://framework.zend.com/manual/1.12/en/learning.multiuser.authentication.html
You use an adapter with the Zend_Auth class to do what you want.