Yii Framework Forum: Creating a backdoor login - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Creating a backdoor login Rate Topic: -----

#1 User is offline   Emily Dickinson 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 201
  • Joined: 17-September 10
  • Location:Albuquerque, NM

Posted 11 January 2011 - 05:33 AM

I'm writing a large app which has two separate areas that folks log in to:

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!
0

#2 User is offline   Jampire 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 53
  • Joined: 10-January 11
  • Location:Gomel, Belarus

Posted 11 January 2011 - 05:59 AM

And why don't you use RBAC? One login with different roles.
Posted Image
0

#3 User is offline   jayrulez 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 348
  • Joined: 29-July 09

Posted 11 January 2011 - 08:48 AM

View PostEmily Dickinson, on 11 January 2011 - 05:33 AM, said:

I'm writing a large app which has two separate areas that folks log in to:

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.
0

#4 User is offline   Emily Dickinson 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 201
  • Joined: 17-September 10
  • Location:Albuquerque, NM

Posted 11 January 2011 - 04:41 PM

Jay - thanks so much, your answer was spot on. The solution below works.

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?

:)
0

#5 User is offline   jayrulez 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 348
  • Joined: 29-July 09

Posted 11 January 2011 - 07:33 PM

View PostEmily Dickinson, on 11 January 2011 - 04:41 PM, said:

Jay - thanks so much, your answer was spot on. The solution below works.

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.
0

#6 User is offline   Emily Dickinson 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 201
  • Joined: 17-September 10
  • Location:Albuquerque, NM

Posted 11 January 2011 - 08:56 PM

Hmm, not sure what you mean. Notice that I actually authenticate in UserIdentity::authenticate(). We look at the session, checking to see if there's a session variable "admin__id". If so, and if it's non-zero, we consider the user session to be a valid "admin" session. My question has to do with just how secure a method of authentication that is. Anyone?
0

#7 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 12 January 2011 - 03:59 AM

Some other approach:

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.
0

#8 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,448
  • Joined: 04-October 10

Posted 14 January 2011 - 05:23 AM

View PostMike, on 12 January 2011 - 03:59 AM, said:

Some other approach:

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
┬┐How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
0

#9 User is offline   Emily Dickinson 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 201
  • Joined: 17-September 10
  • Location:Albuquerque, NM

Posted 20 January 2011 - 10:02 AM

View PostAntonio Ramirez, on 14 January 2011 - 05:23 AM, said:

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.

Hey Antonio -- I haven't seen any updates on this topic -- do you have any? Interested to know what you've learned! ;)
0

#10 User is offline   sanjay1024 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 59
  • Joined: 06-October 12

Posted 13 October 2012 - 03:40 PM

Hi Antonio,

I wanted to the same as of yours.

Can you please update whether you have completed the task, and share us the resource.

Thanks
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users