Creating a backdoor login
#1
Posted 11 January 2011 - 05:33 AM
The site login area is for my customers to log into, to manage their accounts. I refer to this as the customer "portal".
The administrative login area, (a module named "admin"), is where I log in, to manage my customers.
I'd like to build a backdoor such that, if someone is logged in to the "admin" module, they can click on a customer's account name and presto, be logged in that customer's "portal".
Have any of you solved this up--with an elegant solution you're willing to share?
Thanks in advance!
#3
Posted 11 January 2011 - 08:48 AM
Emily Dickinson, on 11 January 2011 - 05:33 AM, said:
The site login area is for my customers to log into, to manage their accounts. I refer to this as the customer "portal".
The administrative login area, (a module named "admin"), is where I log in, to manage my customers.
I'd like to build a backdoor such that, if someone is logged in to the "admin" module, they can click on a customer's account name and presto, be logged in that customer's "portal".
Have any of you solved this up--with an elegant solution you're willing to share?
Thanks in advance!
create a controller/action that only admin will have access to, on the user view you could av a link that is only visible to admin that points to that action.
in the action
check again if current user is admin.
if true, authenticate the current user as the user u want to become
php:
foreach(array('cat', 'dog', 'cow') as $animal) echo $animal."\n";
python:
[(animal, print(animal)) for animal in ['cat', 'dog', 'cow']]
ruby:
['cat', 'dog', 'cow'].each {|animal| puts animal}
You say Tomato, I say Tomato.
#4
Posted 11 January 2011 - 04:41 PM
Again, what this "backdoor" procedure does is to grant an authenticated user in the "admin" module access -- to *ANY* account desired -- in the "portal" module.
See my questions at the bottom--would love advice from security experts.
Steps involved:
// 1. AdminModule::init(). Set stateKeyPrefix to 'admin':
public function init() {
// import the module-level models and components
$this->setImport(array(
'admin.models.*',
'admin.components.*',
));
Yii::app()->setComponents(array(
'user'=>array(
'class'=>'CWebUser',
'stateKeyPrefix'=>'admin',
'loginUrl'=>Yii::app()->createUrl('admin/default/login'),
'returnUrl'=>Yii::app()->createUrl('admin/'),
)));
}
// -----------------------------------------------------------------------
// 2. Modify the portal authentication method -- UserIdentity.php::init()
// -----------------------------------------------------------------------
/**
* Authenticates the user with name given by $this->username -- or grants backdoor access.
* @param $backdoorAs - string - If non-null, then "Authenticate" as the portal user
* with the name $backdoorAs. I.e., we won't truly authenticate, we'll
* instead grant access as long as the currently logged-in user is
* logged in to *admin* module.
* @return boolean whether authentication succeeds.
*
* NOTE: backdoor authentication will NEVER work if you logged in using the actual
* login process. LOG OUT of the portal first.
*/
public function authenticate($backdoorAs=null)
{
$this->errorCode=self::ERROR_NONE;
$backdoor = $backdoorAs !== null; // for readability
if ($backdoor) {
$this->username = $backdoorAs;
}
$user=User::model()->find('LOWER(username)=?',array(strtolower($this->username)));
if($user===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else {
// Backdoor authentication. Allow login if admin session var 'admin__id'
// is non-zero. (Session keys are prepended with the string 'admin' because
// that's how we set up the stateKeyPrefix in AdminModule.php, above.)
if ($backdoor) {
$adminId = Yii::app()->session->itemAt('admin__id');
if ($adminId === null || $adminId < 1) {
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
}
// Else, the usual portal login, validating password
else if (!$user->validatePassword($this->password))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
// User is authentic.
if ($this->errorCode == self::ERROR_NONE) {
$this->_id=$user->id;
$this->username=$user->username;
}
return $this->errorCode==self::ERROR_NONE;
}
// -----------------------------------------------------------------------
// 3. Create a controller for the "portal" module:
// -----------------------------------------------------------------------
/**
* Controller for backdooring in, from admin, to the portal.
*/
class BackdoorController extends Controller
{
/**
* If the current user is an admin user, who has successfully authenticated, and if
* the variable "user" is present as part of the request, then allow this user to view the portal,
* as if logged in as the user specified in the query string.
*/
public function actionIndex()
{
$user= Yii::app()->request->getQuery('user', '');
// If no user, or empty user, quietly redirect.
if (empty($cpanelUser)) {
$this->redirect(Yii::app()->createUrl('portal/'));
return;
}
$password = '';
$identity=new UserIdentity($user, $password);
if ($identity->authenticate($user)) {
$duration= 2592000; // 3600*24*30 = 30 days
Yii::app()->user->login($identity, $duration); // BACKDOOR
}
$this->redirect(Yii::app()->createUrl('portal/'));
} else {
// Authentication failed. Quietly redirect.
$this->redirect(Yii::app()->createUrl('portal/'));
}
}
}
// -----------------------------------------------------------------------
// 4. Create links to the backdoor, in views, etc., in the "admin" module
// -----------------------------------------------------------------------
echo CHtml::link('login as sue',
Yii::app()->createUrl('portal/backdoor', array('user'=>'sue')));
If anyone can add some measures of SECURITY to this implementation, I would appreciate it. My worry, specifically, is that a portal user could guess the backdoor URL :
index.php/portal/backdoor/user/sue
If they were to guess that URL, would it be possible for them to fake the admin__id SESSION variable such that they could gain access to sue's portal? If so, what can I do to make this more secure?
#5
Posted 11 January 2011 - 07:33 PM
Emily Dickinson, on 11 January 2011 - 04:41 PM, said:
Again, what this "backdoor" procedure does is to grant an authenticated user in the "admin" module access -- to *ANY* account desired -- in the "portal" module.
See my questions at the bottom--would love advice from security experts.
Steps involved:
// 1. AdminModule::init(). Set stateKeyPrefix to 'admin':
public function init() {
// import the module-level models and components
$this->setImport(array(
'admin.models.*',
'admin.components.*',
));
Yii::app()->setComponents(array(
'user'=>array(
'class'=>'CWebUser',
'stateKeyPrefix'=>'admin',
'loginUrl'=>Yii::app()->createUrl('admin/default/login'),
'returnUrl'=>Yii::app()->createUrl('admin/'),
)));
}
// -----------------------------------------------------------------------
// 2. Modify the portal authentication method -- UserIdentity.php::init()
// -----------------------------------------------------------------------
/**
* Authenticates the user with name given by $this->username -- or grants backdoor access.
* @param $backdoorAs - string - If non-null, then "Authenticate" as the portal user
* with the name $backdoorAs. I.e., we won't truly authenticate, we'll
* instead grant access as long as the currently logged-in user is
* logged in to *admin* module.
* @return boolean whether authentication succeeds.
*
* NOTE: backdoor authentication will NEVER work if you logged in using the actual
* login process. LOG OUT of the portal first.
*/
public function authenticate($backdoorAs=null)
{
$this->errorCode=self::ERROR_NONE;
$backdoor = $backdoorAs !== null; // for readability
if ($backdoor) {
$this->username = $backdoorAs;
}
$user=User::model()->find('LOWER(username)=?',array(strtolower($this->username)));
if($user===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else {
// Backdoor authentication. Allow login if admin session var 'admin__id'
// is non-zero. (Session keys are prepended with the string 'admin' because
// that's how we set up the stateKeyPrefix in AdminModule.php, above.)
if ($backdoor) {
$adminId = Yii::app()->session->itemAt('admin__id');
if ($adminId === null || $adminId < 1) {
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
}
// Else, the usual portal login, validating password
else if (!$user->validatePassword($this->password))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
// User is authentic.
if ($this->errorCode == self::ERROR_NONE) {
$this->_id=$user->id;
$this->username=$user->username;
}
return $this->errorCode==self::ERROR_NONE;
}
// -----------------------------------------------------------------------
// 3. Create a controller for the "portal" module:
// -----------------------------------------------------------------------
/**
* Controller for backdooring in, from admin, to the portal.
*/
class BackdoorController extends Controller
{
/**
* If the current user is an admin user, who has successfully authenticated, and if
* the variable "user" is present as part of the request, then allow this user to view the portal,
* as if logged in as the user specified in the query string.
*/
public function actionIndex()
{
$user= Yii::app()->request->getQuery('user', '');
// If no user, or empty user, quietly redirect.
if (empty($cpanelUser)) {
$this->redirect(Yii::app()->createUrl('portal/'));
return;
}
$password = '';
$identity=new UserIdentity($user, $password);
if ($identity->authenticate($user)) {
$duration= 2592000; // 3600*24*30 = 30 days
Yii::app()->user->login($identity, $duration); // BACKDOOR
}
$this->redirect(Yii::app()->createUrl('portal/'));
} else {
// Authentication failed. Quietly redirect.
$this->redirect(Yii::app()->createUrl('portal/'));
}
}
}
// -----------------------------------------------------------------------
// 4. Create links to the backdoor, in views, etc., in the "admin" module
// -----------------------------------------------------------------------
echo CHtml::link('login as sue',
Yii::app()->createUrl('portal/backdoor', array('user'=>'sue')));
If anyone can add some measures of SECURITY to this implementation, I would appreciate it. My worry, specifically, is that a portal user could guess the backdoor URL :
index.php/portal/backdoor/user/sue
If they were to guess that URL, would it be possible for them to fake the admin__id SESSION variable such that they could gain access to sue's portal? If so, what can I do to make this more secure?
In BackdoorController::actionIndex you ensure that the current user is authenticated and is a authorized to perform the action.
php:
foreach(array('cat', 'dog', 'cow') as $animal) echo $animal."\n";
python:
[(animal, print(animal)) for animal in ['cat', 'dog', 'cow']]
ruby:
['cat', 'dog', 'cow'].each {|animal| puts animal}
You say Tomato, I say Tomato.
#6
Posted 11 January 2011 - 08:56 PM
#7
Posted 12 January 2011 - 03:59 AM
I've successfully configured 2 webusers in my applications, using a different stateKeyPrefix for the second user. One is for the admin section the other for the frontend section. Now both can login/logout independently.
To have control over the frontend login from the admin section, you could add a static method to your UserIdentity, that creates an authenticated identity without requiring a password (see here). You could use this method in the admin area to create an authenticated fronted identity and use this to force a login as frontend user.
#8
Posted 14 January 2011 - 05:23 AM
Mike, on 12 January 2011 - 03:59 AM, said:
I've successfully configured 2 webusers in my applications, using a different stateKeyPrefix for the second user. One is for the admin section the other for the frontend section. Now both can login/logout independently.
To have control over the frontend login from the admin section, you could add a static method to your UserIdentity, that creates an authenticated identity without requiring a password (see here). You could use this method in the admin area to create an authenticated fronted identity and use this to force a login as frontend user.
Hi, I am also currently developing two major huge projects and one of them will require the Front end for web users and the admin panel that I am also thinking to create it (for my first time) as a module. The admin module panel will be for different type of users and that I can easily handle with rights or roles or whatever, my question is about the front end guys and unifying authentication. What is the best approach? Best practices?
I will have two login areas (user / partners | admin), user will be redirected to profile front-end, partners | admin back-end.
I have seen a couple of solutions, and I think I may know what I can do, but I really would like to know if I am on the right track.
Thanks in advance
www.ramirezcobos.com
#9
Posted 20 January 2011 - 10:02 AM
Antonio Ramirez, on 14 January 2011 - 05:23 AM, said:
Hey Antonio -- I haven't seen any updates on this topic -- do you have any? Interested to know what you've learned!
#10
Posted 13 October 2012 - 03:40 PM
I wanted to the same as of yours.
Can you please update whether you have completed the task, and share us the resource.
Thanks

Help














