adding password authentication for a zend cms or controller

December 13th, 2011

This is a very quick way to add password protection to a controller such as a cms controller.

This code intercepts the login within the init() method of your chosen controller, if they are logged in they are free to go, if not they are required to login, the form is rendered and validated against the access model.

The session is obfuscated to deter tampering.

so firstly in your controller init() add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$adminSession = new Zend_Session_Namespace('Admin');
$this->access = new Application_Model_accessControl(); // access control
 
// logged in user
$loginMsg = 'Please login';
$loginForm = new Zend_Form;
$loginForm
	->setMethod('post')
	->setAttrib('id','login')
	->addElement('text','user',array('label'=>'Username','required'=>true))
	->addElement('password','pass',array('label'=>'Password','required'=>true))
	->addElement('submit','Login');
 
if ($this->getRequest()->isPost() && $loginForm->isValid($_POST)){
	$session = $this->access->validateUser(
		$loginForm->getValue('user'), 
		$loginForm->getValue('pass')
		);
 
	if ($session){
		$adminSession->loggedInSession = $session;
		$adminSession->loggedInUser = $loginForm->getValue('user');
	}
 
	$loginMsg='Access denied';
} 			
 
if (!$this->access->sessionIsValid($adminSession->loggedInSession) || !$adminSession->loggedInUser){
       	$this->view->header=$loginMsg;			
	$this->view->content = $loginForm;
	$this->render('login');  
} else {
	// renew session, will always be the "Now" session, but three are provided, see the model 
	$adminSession->loggedInSession = $this->access->getValidSession();
    	$this->view->userIdent = $adminSession->loggedInUser;
}

$this->view->userIdent will always contain the logged in user

The next step is to create the model for authentication in models/accessControl.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
 
class Application_Model_accessControl
{
 
 
	public function __construct(){
 
		// set users, password is the key, because this is less likely to be duplicated
        $this->setUsers(
        	array(
				'password1'=>'admin',
				'password2'=>'admin'
				)
       		);
        // salt for session key
		$this->setSalt('MySaltGoesHere1234');
	}
 
	public function validateUser($username, $password){
 
		/*
		 * return session if correct, null otherwise
		 */
 
		$users = $this->getUsers();
 
		if (isset($users[$password]) && $users[$password]==$username){
			return $this->getValidSession();
		}
	}
	public function sessionIsValid($session,$debug=false){
 
		$validSessions = $this->getValidSessions();
		if ($debug){
			echo "MY KEY: $session<br >KEYS: ".print_r($validSessions,true);
		}
		return in_array($session, $validSessions) ? true : false;
	}
 
	public function getValidSessions(){
 
		$sessions = array(
			$this->getValidSession('past'),
			$this->getValidSession('now'),
			$this->getValidSession('future')
			);
 
		return $sessions;
	}
	public function getValidSession($for='now'){
 
		/*
		 * Three sessions are provided,
		 * 
		 * past, now and present
		 * 
		 * past, person logs in at 11:59 spends ten minutes editing, clicks save at 12:09, past would be the valid session
		 * now, person is logged in during 11:00 - 11:59
		 * future, is provided encase of time travel, or if the british summer time kicks in while editing, unlikely but more is better than not enough...
		 */
 
		$hour = intval(date('H'));
 
		switch($for){
			case 'past' : 
				$validSession = ($hour-1) < 0 ? 23 : $hour-1;
			break;
			case 'now' : default:
				$validSession = $hour;
			break;
			case 'future' : 
				$validSession = ($hour+1) > 23 ? 0 : $hour+1;
			break;
 
		}
 
		/*
		 * obsfucation
		 */
		// firstly grab specific details to stop session hijacking 
		$ip = $_SERVER['REMOTE_ADDR'];
		$browser = $_SERVER['HTTP_USER_AGENT'];
		// then mix it up and md5 it
		$validSession = $ip.$validSession.$this->getSalt().$browser;
 
		if (!getenv('APPLICATION_ENV')){
			$validSession = md5($validSession);
		}
 
		return $validSession;
	}
 
	public function setUsers($users){
		$this->users = $users;
	}
	public function getUsers(){
		return $this->users;
	}
	public function setSalt($salt){
		$this->salt = $salt;
	}
	public function getSalt(){
		return $this->salt;
	}
 
 
}

and finally create a view login.phtml (this is just bare bones)

1
2
<?php echo "<h2>{$this->header}</h2>";  ?>
<?php echo $this->content;  ?>

Thats it!

VN:F [1.9.9_1125]
Rating: 8.3/10 (3 votes cast)
VN:F [1.9.9_1125]
Rating: 0 (from 0 votes)
8,572 views

session_start hangs when it used to work

December 13th, 2011

I had a problem with my zend application hanging with a white screen for no reason.
I narrowed it down to when

1
$adminSession = new Zend_Session_Namespace('Admin');

was executed, this is just a session? so debugging further, confirmed that session_start() hangs when it used to work.

There are lots of explanations for this, but before you start modifying ini settings, just try this

1
2
3
session_write_close();
session_start();
die(print_r($_SESSION,true));

I found this resolved the problem completely.
I then just removed this debug-code and went back to developing my zend app.

VN:F [1.9.9_1125]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.9_1125]
Rating: +1 (from 1 vote)
3,722 views