Subversion Repositories Applications.papyrus

Rev

Rev 2154 | Rev 2156 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2154 Rev 2155
1
<?php
1
<?php
2
 
2
 
3
// Remplacement de apache_request_headers pour les vieux serveurs
3
// Remplacement de apache_request_headers pour les vieux serveurs
4
// http://stackoverflow.com/questions/2916232/call-to-undefined-function-apache-request-headers
4
// http://stackoverflow.com/questions/2916232/call-to-undefined-function-apache-request-headers
5
if(!function_exists('apache_request_headers')) {
5
if(!function_exists('apache_request_headers')) {
6
	function apache_request_headers() {
6
	function apache_request_headers() {
7
		// Based on: http://www.iana.org/assignments/message-headers/message-headers.xml#perm-headers
7
		// Based on: http://www.iana.org/assignments/message-headers/message-headers.xml#perm-headers
8
		$arrCasedHeaders = array(
8
		$arrCasedHeaders = array(
9
				// HTTP
9
				// HTTP
10
				'Dasl'             => 'DASL',
10
				'Dasl'             => 'DASL',
11
				'Dav'              => 'DAV',
11
				'Dav'              => 'DAV',
12
				'Etag'             => 'ETag',
12
				'Etag'             => 'ETag',
13
				'Mime-Version'     => 'MIME-Version',
13
				'Mime-Version'     => 'MIME-Version',
14
				'Slug'             => 'SLUG',
14
				'Slug'             => 'SLUG',
15
				'Te'               => 'TE',
15
				'Te'               => 'TE',
16
				'Www-Authenticate' => 'WWW-Authenticate',
16
				'Www-Authenticate' => 'WWW-Authenticate',
17
				// MIME
17
				// MIME
18
				'Content-Md5'      => 'Content-MD5',
18
				'Content-Md5'      => 'Content-MD5',
19
				'Content-Id'       => 'Content-ID',
19
				'Content-Id'       => 'Content-ID',
20
				'Content-Features' => 'Content-features',
20
				'Content-Features' => 'Content-features',
21
		);
21
		);
22
		$arrHttpHeaders = array();
22
		$arrHttpHeaders = array();
23
 
23
 
24
		foreach($_SERVER as $strKey => $mixValue) {
24
		foreach($_SERVER as $strKey => $mixValue) {
25
			if('HTTP_' !== substr($strKey, 0, 5)) {
25
			if('HTTP_' !== substr($strKey, 0, 5)) {
26
				continue;
26
				continue;
27
			}
27
			}
28
 
28
 
29
			$strHeaderKey = strtolower(substr($strKey, 5));
29
			$strHeaderKey = strtolower(substr($strKey, 5));
30
 
30
 
31
			if(0 < substr_count($strHeaderKey, '_')) {
31
			if(0 < substr_count($strHeaderKey, '_')) {
32
				$arrHeaderKey = explode('_', $strHeaderKey);
32
				$arrHeaderKey = explode('_', $strHeaderKey);
33
				$arrHeaderKey = array_map('ucfirst', $arrHeaderKey);
33
				$arrHeaderKey = array_map('ucfirst', $arrHeaderKey);
34
				$strHeaderKey = implode('-', $arrHeaderKey);
34
				$strHeaderKey = implode('-', $arrHeaderKey);
35
			}
35
			}
36
			else {
36
			else {
37
				$strHeaderKey = ucfirst($strHeaderKey);
37
				$strHeaderKey = ucfirst($strHeaderKey);
38
			}
38
			}
39
 
39
 
40
			if(array_key_exists($strHeaderKey, $arrCasedHeaders)) {
40
			if(array_key_exists($strHeaderKey, $arrCasedHeaders)) {
41
				$strHeaderKey = $arrCasedHeaders[$strHeaderKey];
41
				$strHeaderKey = $arrCasedHeaders[$strHeaderKey];
42
			}
42
			}
43
 
43
 
44
			$arrHttpHeaders[$strHeaderKey] = $mixValue;
44
			$arrHttpHeaders[$strHeaderKey] = $mixValue;
45
		}
45
		}
46
		return $arrHttpHeaders;
46
		return $arrHttpHeaders;
47
	}
47
	}
48
}
48
}
49
 
49
 
50
class identificationSso {
50
class identificationSso {
51
	
51
	
52
	// Attention bien vérifier la présence des variables suivantes :
52
	// Attention bien v�rifier la pr�sence des variables suivantes :
53
	// IDEN_UTILISE_SSO, IDEN_URL_SSO, IDEN_HEADER_SSO, IDEN_COOKIE_SSO
53
	// IDEN_UTILISE_SSO, IDEN_URL_SSO, IDEN_HEADER_SSO, IDEN_COOKIE_SSO
54
	// dans le fichier iden_config.inc.php
54
	// dans le fichier iden_config.inc.php
55
	private $cookie_tentative_identification = "";
55
	private $cookie_tentative_identification = "";
-
 
56
	/** Une tentative par minute pour s'identifier suffit largement */
56
	private $delai_tentative_identification = 60;
57
	private $delai_tentative_identification = 60;
57
	
58
	
58
	private $auth_header = 'Authorization';
59
	private $auth_header = 'Authorization';
59
	
60
	
60
	private $annuaire_url = '';
61
	private $annuaire_url = '';
61
	
62
	
62
	private $bdd_annuaire = '';
63
	private $bdd_annuaire = '';
63
	private $table_annuaire = '';
64
	private $table_annuaire = '';
64
	private $champ_login = '';
65
	private $champ_login = '';
65
	private $champ_mdp = '';
66
	private $champ_mdp = '';
66
	
67
	
67
	private $communs_papyrus = null;
68
	private $communs_papyrus = null;
68
 
69
 
69
	public function __construct() {
70
	public function __construct() {
70
		$this->communs_papyrus = $GLOBALS['_GEN_commun'];
71
		$this->communs_papyrus = $GLOBALS['_GEN_commun'];
71
		
72
		
72
		$this->cookie_tentative_identification = IDEN_COOKIE_SSO;
73
		$this->cookie_tentative_identification = IDEN_COOKIE_SSO;
73
		$this->auth_header = IDEN_HEADER_SSO;	
74
		$this->auth_header = IDEN_HEADER_SSO;	
74
		$this->annuaire_url = IDEN_URL_SSO;
75
		$this->annuaire_url = IDEN_URL_SSO;
75
		
76
		
76
		// c'est moche mais je n'ai pas trouvé plus simple pour récuperer la table annuaire en cours 
77
		// c'est moche mais je n'ai pas trouv� plus simple pour r�cuperer la table annuaire en cours 
77
		// d'utilisation pour le site actuel (la bdd annuaire est la dernière partie du dsn)
78
		// d'utilisation pour le site actuel (la bdd annuaire est la derni�re partie du dsn)
78
		$dsn_annuaire = $this->communs_papyrus['info_auth_bdd']->gsab_dsn;
79
		$dsn_annuaire = $this->communs_papyrus['info_auth_bdd']->gsab_dsn;
79
		$dsn_annuaire = explode('/', $dsn_annuaire);
80
		$dsn_annuaire = explode('/', $dsn_annuaire);
80
		$this->bdd_annuaire = end($dsn_annuaire);
81
		$this->bdd_annuaire = end($dsn_annuaire);
81
		
82
		
82
		$this->table_annuaire = $this->communs_papyrus['info_auth_bdd']->gsab_nom_table;
83
		$this->table_annuaire = $this->communs_papyrus['info_auth_bdd']->gsab_nom_table;
83
		$this->champ_login = $this->communs_papyrus['info_auth_bdd']->gsab_nom_champ_login;
84
		$this->champ_login = $this->communs_papyrus['info_auth_bdd']->gsab_nom_champ_login;
84
		$this->champ_mdp = $this->communs_papyrus['info_auth_bdd']->gsab_nom_champ_mdp;
85
		$this->champ_mdp = $this->communs_papyrus['info_auth_bdd']->gsab_nom_champ_mdp;
85
	}
86
	}
86
 
87
 
87
	function getToken() {
88
	function getToken() {
88
		// Premier essai, dans le header
89
		// Premier essai, dans le header
89
		$headers = @apache_request_headers();
90
		$headers = @apache_request_headers();
90
		$token = !empty($headers['Authorization']) ? $headers['Authorization'] : null;
91
		$token = !empty($headers['Authorization']) ? $headers['Authorization'] : null;
91
		// Eventuellement, le jeton a pu être passé dans un header non standard, comme dans 
92
		// Eventuellement, le jeton a pu �tre pass� dans un header non standard, comme dans 
92
		// le cas où le header Authorization est supprimé par le mod cgi d'apache
93
		// le cas o� le header Authorization est supprim� par le mod cgi d'apache
93
		// Dans ce cas là on vérifie aussi dans un header alternatif si celui ci a été renseigné
94
		// Dans ce cas l� on v�rifie aussi dans un header alternatif si celui ci a �t� renseign�
94
		if($token == null && $this->auth_header != 'Authorization') {
95
		if($token == null && $this->auth_header != 'Authorization') {
95
			$token = !empty($headers[$this->auth_header]) ? $headers[$this->auth_header] : null;
96
			$token = !empty($headers[$this->auth_header]) ? $headers[$this->auth_header] : null;
96
		}
97
		}
97
 
98
 
98
		// Sinon dans $_REQUEST ?
99
		// Sinon dans $_REQUEST ?
99
		if($token == null) {
100
		if($token == null) {
100
			$token = !empty($_REQUEST['Authorization']) ? $_REQUEST['Authorization'] : null;
101
			$token = !empty($_REQUEST['Authorization']) ? $_REQUEST['Authorization'] : null;
101
		}
102
		}
102
		
103
		
103
		// Sinon dans $_COOKIE ?
104
		// Sinon dans $_COOKIE ?
104
		if($token == null) {
105
		if($token == null) {
105
			$token = !empty($_COOKIE['tb_auth']) ? $_COOKIE['tb_auth'] : null;
106
			$token = !empty($_COOKIE['tb_auth']) ? $_COOKIE['tb_auth'] : null;
106
		}
107
		}
107
 
108
 
108
		return $token;
109
		return $token;
109
	}
110
	}
110
 
111
 
111
	public function decoderToken($token) {
112
	public function decoderToken($token) {
112
		$token_parts = explode('.', $token);
113
		$token_parts = explode('.', $token);
113
		return json_decode(base64_decode($token_parts[1]), true);
114
		return json_decode(base64_decode($token_parts[1]), true);
114
	}
115
	}
115
 
116
 
116
	// http://stackoverflow.com/questions/1251582/beautiful-way-to-remove-get-variables-with-php?lq=1
117
	// http://stackoverflow.com/questions/1251582/beautiful-way-to-remove-get-variables-with-php?lq=1
117
	function supprimerUrlVar($url, $var) {
118
	function supprimerUrlVar($url, $var) {
118
		 return rtrim(preg_replace('/([?&])'.$var.'=[^&]+(&|$)/','$1',$url), '&?');
119
		 return rtrim(preg_replace('/([?&])'.$var.'=[^&]+(&|$)/','$1',$url), '&?');
119
	}
120
	}
120
	
121
	
121
	function connecterEtRediriger($utilisateur, $pass) {
122
	function connecterEtRediriger() {
122
		$url_redirect = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
123
		$url_redirect = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
123
		$params = 'login='.$_POST['username'].'&password='.$_POST['password'].'&redirect_url='.urlencode($url_redirect);
124
		$params = 'login='.$_POST['username'].'&password='.$_POST['password'].'&redirect_url='.urlencode($url_redirect);
124
		$connexion_url = $this->annuaire_url."connexion?".$params;
125
		$connexion_url = $this->annuaire_url."connexion?".$params;
125
		
126
		
126
		header('Location: '.$connexion_url);
127
		header('Location: '.$connexion_url);
127
		exit;
128
		exit;
128
	}
129
	}
129
	
130
	
130
	function deconnecterEtRediriger() {
131
	function deconnecterEtRediriger() {
131
		$url_redirect = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
132
		$url_redirect = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
132
		$url_redirect = $this->supprimerUrlVar($url_redirect, 'logout');
133
		$url_redirect = $this->supprimerUrlVar($url_redirect, 'logout');
133
		
134
		
134
		$deconnexion_url = $this->annuaire_url."deconnexion?".'redirect_url='.urlencode($url_redirect);
135
		$deconnexion_url = $this->annuaire_url."deconnexion?".'redirect_url='.urlencode($url_redirect);
135
		
136
		
136
		header('Location: '.$deconnexion_url);
137
		header('Location: '.$deconnexion_url);
137
		exit;
138
		exit;
138
	}
139
	}
139
	
140
	
140
	function verifierIdentiteEtRediriger() {
141
	function verifierIdentiteEtRediriger() {
141
				
-
 
-
 
142
		// si on fait autre chose qu'un GET, on ne vérifie pas l'identité, car
-
 
143
		// cela conduirait à une redirection en GET (avec le jeton), qui
-
 
144
		// supprimerait les données du corps de la requête
-
 
145
		if ($_SERVER['REQUEST_METHOD'] == "GET") {
142
		if(empty($_COOKIE['sso_tentative_identification'])) {
146
			if(empty($_COOKIE['sso_tentative_identification'])) {
143
 
147
 
144
			if($this->communs_papyrus['pear_auth']->getAuth()) {
148
				if($this->communs_papyrus['pear_auth']->getAuth()) {
145
				
149
 
146
				$cookie_persistant_nom = session_name().'-memo';
150
					$cookie_persistant_nom = session_name().'-memo';
147
				$cookie_utilisateur_nom = session_name().'-utilisateur';
151
					$cookie_utilisateur_nom = session_name().'-utilisateur';
148
				
152
 
149
				// Si l'utilisateur est déjà connecté par pear
153
					// Si l'utilisateur est d�j� connect� par pear
150
				// on fait tout de même une opération de logout
154
					// on fait tout de m�me une op�ration de logout
151
				// pour coordonner la déconnection depuis une autre application
155
					// pour coordonner la d�connection depuis une autre application
152
				$this->communs_papyrus['pear_auth']->logout();
156
					$this->communs_papyrus['pear_auth']->logout();
153
				// Destruction du cookie de session de Papyrus : est ce utile?
157
					// Destruction du cookie de session de Papyrus : est ce utile?
154
				setcookie(session_name(), session_id(), time()-3600, '/');
158
					setcookie(session_name(), session_id(), time()-3600, '/');
155
				// Destruction du cookie de permanence de l'identitification de Papyrus
159
					// Destruction du cookie de permanence de l'identitification de Papyrus
156
				setcookie($cookie_persistant_nom, '', time()-3600, '/');
160
					setcookie($cookie_persistant_nom, '', time()-3600, '/');
157
				setcookie($cookie_utilisateur_nom, '', time()-3600, '/');
161
					setcookie($cookie_utilisateur_nom, '', time()-3600, '/');
158
			}
-
 
159
		
-
 
160
			$url_redirect = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
-
 
161
			$url = $this->annuaire_url."identite?redirect_url=".urlencode($url_redirect);
-
 
162
						
-
 
163
			// une tentative par minute pour s'identifier suffit largement
-
 
164
			setcookie($this->cookie_tentative_identification, 1, time()+60, '/');
-
 
165
	
-
 
166
			header('Location: '.$url);
-
 
167
		
-
 
168
		} else {	
-
 
169
			$jeton = $this->getToken();
-
 
170
 
-
 
171
			if($jeton != null) {
-
 
172
				$jeton_decode = $this->decoderToken($jeton);
-
 
173
				
-
 
174
				// Récupération du mot de passe pour remplir les infos de l'objet PEAR Auth
-
 
175
				$requete =  'SELECT '.$this->champ_mdp.' '.
-
 
176
						'FROM '.$this->bdd_annuaire.'.'.$this->table_annuaire.' '.
-
 
177
						'WHERE '.$this->champ_login.' = "'.$jeton_decode['sub'].'" ';
-
 
178
				
-
 
179
				// TODO: normalement ça n'est jamais le cas mais que fait t'on si l'utilisateur n'existe pas
-
 
180
				// dans notre base de données ? (au pire il ne sera pas connecté)
-
 
181
	
-
 
182
				$this->communs_papyrus['pear_auth']->username = $jeton_decode['sub'];
-
 
183
				$this->communs_papyrus['pear_auth']->password = $this->communs_papyrus['pear_db']->getOne($requete);
-
 
184
					
-
 
185
				// Le mot de passe est déjà crypté dans la bdd donc il faut indiquer à pear de ne pas le re crytper
-
 
186
				if (isset($this->communs_papyrus['pear_auth']->storage_options)) {
-
 
187
					$this->communs_papyrus['pear_auth']->storage_options['cryptType'] = 'none';
-
 
188
				}
162
				}
-
 
163
 
-
 
164
				$url_redirect = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
-
 
165
				$url = $this->annuaire_url."identite?redirect_url=".urlencode($url_redirect);
-
 
166
 
-
 
167
				// une tentative toutes les $this->delai_tentative_identification
-
 
168
				setcookie($this->cookie_tentative_identification, 1, time() + $this->delai_tentative_identification, '/');
-
 
169
 
-
 
170
				header('Location: '.$url);
-
 
171
 
-
 
172
			} else {
-
 
173
				$jeton = $this->getToken();
-
 
174
 
-
 
175
				if($jeton != null) {
-
 
176
					// Verification du jeton aupres de l'annuaire
-
 
177
					$valide = $this->verifierToken($jeton);
-
 
178
					if ($valide === true) {
-
 
179
						$jeton_decode = $this->decoderToken($jeton);
-
 
180
 
-
 
181
						// R�cup�ration du mot de passe pour remplir les infos de l'objet PEAR Auth
-
 
182
						$requete =  'SELECT '.$this->champ_mdp.' '.
-
 
183
								'FROM '.$this->bdd_annuaire.'.'.$this->table_annuaire.' '.
-
 
184
								'WHERE '.$this->champ_login.' = "'.$jeton_decode['sub'].'" ';
-
 
185
 
-
 
186
						// TODO: normalement �a n'est jamais le cas mais que fait t'on si l'utilisateur n'existe pas
-
 
187
						// dans notre base de donn�es ? (au pire il ne sera pas connect�)
-
 
188
 
-
 
189
						$this->communs_papyrus['pear_auth']->username = $jeton_decode['sub'];
-
 
190
						$this->communs_papyrus['pear_auth']->password = $this->communs_papyrus['pear_db']->getOne($requete);
-
 
191
 
-
 
192
						// Le mot de passe est d�j� crypt� dans la bdd donc il faut indiquer � pear de ne pas le re crytper
-
 
193
						if (isset($this->communs_papyrus['pear_auth']->storage_options)) {
-
 
194
							$this->communs_papyrus['pear_auth']->storage_options['cryptType'] = 'none';
-
 
195
						}
189
				if (isset($this->communs_papyrus['pear_auth']->storage->options)) {
196
						if (isset($this->communs_papyrus['pear_auth']->storage->options)) {
190
					$this->communs_papyrus['pear_auth']->storage->options['cryptType'] = 'none';
197
							$this->communs_papyrus['pear_auth']->storage->options['cryptType'] = 'none';
-
 
198
						}
-
 
199
					}
191
				}
200
				}
192
			}
201
			}
193
		}
202
		}
194
	}
203
	}
-
 
204
 
-
 
205
	/**
-
 
206
	 * Vérifie un jeton auprès de l'annuaire
-
 
207
	 */
-
 
208
	protected function verifierToken($token) {
-
 
209
		$verificationServiceURL = $this->annuaire_url . "verifytoken";
-
 
210
		$verificationServiceURL .= "?token=" . $token;
-
 
211
 
-
 
212
		$info = file_get_contents($verificationServiceURL);
-
 
213
		$info = json_decode($info, true);
-
 
214
 
-
 
215
		return ($info === true);
-
 
216
	}
195
}
217
}
196
?>
218
?>