I have a table which splits my users (user_levels) linked to the users table (user_level_id). Level 5 is administrator.
I want to limit certain actions from being viewed and understand I can do this with isAuthorized. I went according to book and I am pretty sure I have it right, but it is not working. It allows any logged in users to still access any of the actions although I deny it in isAuthorized.
Here is my code:
App Controller:public $components = array(
'Session',
'Auth' => array(
'loginAction' => array(
'controller' => 'users',
'action' => 'login',
),
'authError' => "Your username and password is incorrect, please try again.",
'authenticate' => array(
'Form' => array(
'scope' => array('User.user_status_id' => 1)
)
),
'redirect' => array("controller" => "users", "action" => "profile"),
'loginRedirect' => array("controller" => "users", "action" => "profile")
)
);
public function isAuthorized($user = null) {
if($this->Auth->user("user_level_id") == 5) {
return true;
}
// Default deny
return false;
}
public function beforeFilter() {
$this->Auth->allow("display");
if($this->Auth->loggedIn() == true) {
$this->set("user_name",$this->Auth->user("first_name")." ".$this->Auth->user("last_name"));
$this->set("loggedIn",true);
if($this->Auth->user("user_type_id") == 5) {
$this->set("navigation","navigation_admin");
} else {
$this->set("navigation","navigation_loggedin");
}
} else {
$this->set("loggedIn",false);
$this->set("navigation","navigation_notloggedin");
}
}
}
// Users Controller:
public function beforeFilter() {
$this->Auth->allow("login");
parent::beforeFilter();
}
public function isAuthorized($user = null) {
if($this->Auth->user("user_level_id") == 5) {
return true;
}
// Default deny
return parent::isAuthorized($user);
}
Looks like you're just missing the configuration to just tell the AuthComponent to use isAuthorized().
'Auth' => array(
'loginAction' => array(
'controller' => 'users',
'action' => 'login',
),
'authError' => "Your username and password is incorrect, please try again.",
'authenticate' => array(
'Form' => array(
'scope' => array('User.user_status_id' => 1)
)
),
'authorize' => array('Controller'), // <- here
'redirect' => array("controller" => "users", "action" => "profile"),
'loginRedirect' => array("controller" => "users", "action" => "profile")
)
Related
I have been trying to get the CakePHP ACL's working with my new application, it is causing me a world of pain. For some reason the ACL doesnt seem to be working however the tutorials are rubbish and don't explain each component very well. e.g. how a ACO links to a controller / function / views
I have got the ACL working correctly up until getting the pages to know if the user is allowed to view it, also same issue with menu items that they can / cant see.
I have noticed that if i add this code to my page the array shows the group as blank:
$user = $this->Auth->user();
pr($user);
The array returned:
Array
(
[id] => 80
[first_name] => Bob
[last_name] => Test
[email] => email#emial.com
[username] => TestAdmin
[tokenhash] => cleared
[is_active] => 1
[created] => 2014-10-03 16:32:45
[modified] => 2014-10-03 16:32:45
[token_expires_at] =>
[group_id] => 3
[Group] => Array
(
[id] =>
[name] =>
[enabled] =>
[created] =>
[modified] =>
)
)
The site is basically a portal, visitors should only have access to login / register. and the users groups all have access to the dashboard however it ends up in a continuous loop unless i allow everyone access to the dashboard (due to the group not being recognised i guess)
any help would be appreciated, I realise that you may need me to post the code im using so please let me know what you would require.
Thanks in advance
EDIT:
I have updated my AppController as below and it has started showing the group in the array as it should!!! weird thanks for the push in the right direction.
AppController.php
<?php
App::uses('Controller', 'Controller');
class AppController extends Controller {
public function beforeRender() {
if((($this->params['controller']==='Users') || ($this->params['controller']==='users'))&&(($this->params['action']=='login') || ($this->params['action']=='register') || ($this->params['action']=='success') || ($this->params['action']=='forgot_password') || ($this->params['action']=='reset_password')) ){
$this->theme = 'DataHouseLogin';
}else{
$this->theme = 'DataHouse';
}
parent::beforeRender();
}
public $components = array(
'Acl',
'RequestHandler',
'DebugKit.Toolbar' => array('panels' => array('history' => false)),
'Session',
'Auth' => array(
'authorize' => array(
'Actions' => array(
'actionPath' => 'controllers'
)
),
'loginAction' => array(
'controller' => 'Users',
'action' => 'login'
),
'loginRedirect' => array(
'controller' => 'Dashboard',
'action' => 'index'
),
'logoutRedirect' => array(
'controller' => 'Users',
'action' => 'login'
),
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => array(
'Form' => array(
'passwordHasher' => 'Blowfish'
)
)
)
);
public function beforeFilter() {
//$this->Auth->allowedActions = array('display','index','register');
$this->set('user', $this->Auth->user());
$this->set('acl', $this->Acl);
$this->Auth->authorize = array(
'Controller',
'Actions' => array('actionPath' => 'controllers')
);
parent::beforeFilter();
}
public function isAuthorized($user) {
// Default deny
return false;
}
}
I think you should try to configure Auth component correctly. Try to put this code in your AppController:
class AppController extends Controller {
public $components = array('RequestHandler', 'Session',
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
);
public function beforeFilter() {
$this->Auth->authorize = array(
'Controller',
'Actions' => array('actionPath' => 'controllers')
);
$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'name', 'password' => 'password')));
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login', 'admin' => false, 'plugin' => false);
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login', 'admin' => false, 'plugin' => false);
}
public function isAuthorized($user) {
// Default deny
return false;
}
}
EDIT:
in UserModel and GroupModel add act as property:
public $actsAs = array('Acl' => array('type' => 'requester'));
in UserModel setup parentNode function:
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['group_id'])) {
$groupId = $this->data['User']['group_id'];
} else {
$groupId = $this->field('group_id');
}
if (!$groupId) {
return null;
} else {
return array('Group' => array('id' => $groupId));
}
}
I have 2 admin roles (super, admin), at first login, everything works fine but after logout and login as a different admin, it redirect be to the super prefix.
Here is my app controller:
class AppController extends Controller {
public $helpers = array('Js', 'Session');
public $components = array(
'Session',
'RequestHandler',
'DebugKit.Toolbar',
'Auth' => array(
'autoRedirect' => false,
'loginAction' => array(
'admin' => false,
'super' => false,
'controller' => 'users',
'action' => 'login'
),
'loginRedirect' => array(
'controller' => 'users',
'action' => 'dashboard',
'admin'=> true,
'super'=> true
),
'logoutRedirect' => array(
'admin' => false,
'super' => false,
'controller' => 'users',
'action' => 'login'
),
'authError' => 'Please login to continue.',
'flash' => array('element' => 'flash/default', 'key' => 'auth', 'params' => array('class' => 'error', 'title' => 'Authentication Error')),
'authorize' => 'Controller',
'authenticate' => array(
'Form' => array(
'userModel' => 'User',
'fields' => array(
'username' => 'email'
),
)
),
)
);
public function isAuthorized($user) {
# Accept if Admin
if($user['admin']){
return true;
}
# Check if current prefix is admin or physician and authenticate user
if(isset($this->request->prefix)) {
switch ($this->request->prefix) {
case 'super':
if(!$user['super']){
$this->Auth->authError = 'Sorry, you do not have permission to access the Manager\'s area';
}
return $user['super'];
break;
case 'admin':
if(!$user['admin']){
$this->Auth->authError = 'Sorry, you do not have permission to access the Administrators\'s area';
}else{
$this->layout = 'admin_layout';
}
return $user['admin'];
break;
}
}else{
$this->layout = 'super_layout';
return true;
}
$this->Auth->authError = 'Sorry, you do not have permission to access the Admin area';
return false;
}
public function beforefilter(){
$this->appSettings = Configure::read('appSettings');
$this->set('appSettings', Configure::read('appSettings'));
if (!$this->Auth->loggedIn()) {
$this->Auth->authError = false;
}
if(isset($this->request->prefix)) {
switch ($this->request->prefix) {
case 'admin':
$this->layout = 'admin_layout';
$admin = true;
break;
case 'super':
$this->layout = 'super_layout';
$super = true;
break;
}
}
}
property AuthComponent::$loginRedirect
The URL (defined as a string or array) to the controller action users should be redirected to after logging in. This value will be ignored if the user has an Auth.redirect value in their session.
If you tried accessed domain.com/super/ and tried to login as an admin, cake will ignore the $loginRedirect attribute and after you login , it will try to redirect you to domain.com/super/ which is the link you tried to access at first
I need a login/logout system in my project I've done an authorization class but It won't work for me because the login function always returns false
Here is my UserController.php
if ($this->request->is('post')) {
$this->Auth->fields = array("username"=>"username","password"=>"password");
debug($this->Auth->login(),false,true);
if ($this->Auth->login()) {
$this->Session->setFlash(__('You are now logged in.'));
}else{
$this->Session->setFlash(__('Invalid username or password, try again'));
}
Configure::write('debug', 2);
$log = $this->User->getDataSource()->getLog(false, false);
debug($log);
}
Also, my AppController.php have:
public $components = array(
'Session',
'Auth' => array(
'loginAction' => array(
'controller' => 'User',
'action' => 'login'
),
'loginRedirect' => array('controller' => 'User', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'User', 'action' => 'login'),
'authError' => "You can't acces that page",
'authorize' => array('Controller'),
));
public function isAuthorized(){
return TRUE;
}
public function beforeFilter() {
$this->Auth->authenticate = array('Form');
$this->Auth->allow('index', 'view');
}
And finally my model file is:
public $validate = array(
'email' => array(
'required' => array(
'rule' => array("notEmpty"),
'message' => 'A E-mail field is required'
)
),'password' => array(
'required' => array(
'rule' => array("notEmpty"),
'message' => "A Password field is required"
)
)
);
I'm using Employees as the model to handle usernames and password. It does redirect to the correct Controller and action but $this->Auth->login() doesn't seem to be working correctly. Does anyone see a problem?
EmployeesController
public function index() {
//Set layout to login
$this->layout = 'login';
//Set salt
//Convert user password to md5
$this->request->data['password'] = md5($this->request->data['password'].$salt);
//if already logged-in, redirect
if($this->Session->check('Auth.User')){
$this->redirect(array('action' => 'index'));
}
if ($this->request->is('post')) {
echo "here";
if ($this->Auth->login()) {
echo $this->Auth->user('username');
$this->redirect($this->Auth->redirectUrl());
} else {
echo "Invlaid Username";
}
}
}
AppController
public $components = array(
'Session',
'Auth' => array(
'loginAction' => array(
'controller' => 'Employees',
'action' => 'index',
),
'authenticate' => array(
'all' => array('userModel' => 'Employee'),
'Form' => array(
'userModel' => 'Employee',
'fields' => array(
'username' => 'employee_id',
'password' => 'password',
)
)
)
),
);
print_r of $this->request->data
Array ( [Employee] => Array ( [username] => tmoorlag [password] => a8c407a6218250985ccd24ff9ec6 ) )
It should be
$this->request->data['Employee']['password'] = md5($this->request->data['Employee']['password'].$salt);
I don't have a User table. I got a Customer table. It seems like Cakephp Auth doesn't recognise any other table beside User. Is there any way to walk around this error?
If I tried using $this->Auth->User('role') - it works perfectly fine. But all my auth credentials is under the Customer table. please help.
I got this error below
Fatal error: Call to undefined method AuthComponent::Customer() in
/Applications/MAMP/htdocs/development03/app/app_controller.php on line 56
The code:
function beforeFilter() {
$this->set('admin', $this->_isAdmin());
}
function _isAdmin() {
$admin = FALSE;
if ($this->Auth->Customer('role') == 'admin') {
$admin = TRUE;
}
return $admin;
}
Let's say that you want administrators table where username is field email and password is field password:
In your AppController.php:
public $components = array('Session',
'Auth' => array('authenticate' => array('Form' => array( 'userModel' => 'Administrator',
'fields' => array(
'username' => 'email',
'password' => 'password'
)
)
),
'authorize' => array('Controller'),
'loginAction' => array('controller' => 'administrators', 'action' => 'login'),
'loginRedirect' => array('controller' => 'Home', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'Home', 'action' => 'index'),
),
);
In AppController.php add this too:
public function isAuthorized($user){
return true;
}
You will have to use userModel => ModelName property. Your AppController should looks like:
class AppController extends Controller
{
public $components = array(
'Auth' => array('authenticate' => array('Form' => array('userModel' =>'Customer',
'fields' => array('username' => 'USER_LOGINNAME', 'password' => 'USER_PASSWORD'
)
)
)
)
);
/*...... Your code ............*/
}
This link might help you to resolve bugs.