Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
auth.php
1<?php
10
11
20
21class Auth
22{
23 const AUTH_TYPE = 'oauth';
24
25 const CACHE_TTL = 3600;
26 const CACHE_PREFIX = "oauth_";
27
28 const PARAM_LOCAL_USER = 'LOCAL_USER';
29 const PARAM_TZ_OFFSET = 'TZ_OFFSET';
30
34 protected static $storage = null;
35
36 protected static $authQueryParams = array(
37 'auth', 'access_token'
38 );
39
40 protected static $authQueryAdditional = array(
41 'auth_connector'
42 );
43
47 public static function authorizeClient($clientId, $userId, $state = '')
48 {
49 return Application::getAuthProvider()->authorizeClient($clientId, $userId, $state);
50 }
51
55 public static function get($clientId, $scope, $additionalParams, $userId)
56 {
57 return Application::getAuthProvider()->get($clientId, $scope, $additionalParams, $userId);
58 }
59
60 public static function storeRegisteredAuth(array $tokenInfo)
61 {
62 static::getStorage()->store($tokenInfo);
63 }
64
65 public static function onRestCheckAuth(array $query, $scope, &$res)
66 {
67 $authKey = static::getAuthKey($query);
68
69 if($authKey)
70 {
71 $tokenInfo = static::check($authKey);
72 if(is_array($tokenInfo))
73 {
74 $error = array_key_exists('error', $tokenInfo);
75
76 if(!$error && !array_key_exists('client_id', $tokenInfo))
77 {
78 $tokenInfo = array('error' => 'CONNECTION_ERROR', 'error_description' => 'Error connecting to authorization server');
79 $error = true;
80 }
81
82 if (!$error && HoldEntity::is(HoldEntity::TYPE_APP, $tokenInfo['client_id']))
83 {
84 $tokenInfo = [
85 'error' => 'OVERLOAD_LIMIT',
86 'error_description' => 'REST API is blocked due to overload.'
87 ];
88 $error = true;
89 }
90
91 if (
92 !$error
93 && (
94 !Access::isAvailable($tokenInfo['client_id'])
95 || (
97 && !Access::isAvailableCount(Access::ENTITY_TYPE_APP, $tokenInfo['client_id'])
98 )
99 )
100 )
101 {
102 $tokenInfo = [
103 'error' => 'ACCESS_DENIED',
104 'error_description' => 'REST is available only on commercial plans.'
105 ];
106 $error = true;
107 }
108
109 if(!$error)
110 {
111 $clientInfo = AppTable::getByClientId($tokenInfo['client_id']);
112 if(is_array($clientInfo))
113 {
114 \CRestUtil::updateAppStatus($tokenInfo);
115 }
116
117 if(!is_array($clientInfo) || $clientInfo['ACTIVE'] !== 'Y')
118 {
119 $tokenInfo = array('error' => 'APPLICATION_NOT_FOUND', 'error_description' => 'Application not found');
120 $error = true;
121 }
122 }
123
124 if(!$error && $tokenInfo['expires'] <= time())
125 {
126 $tokenInfo = array('error' => 'expired_token', 'error_description' => 'The access token provided has expired');
127 $error = true;
128 }
129
130 if(!$error && $scope !== \CRestUtil::GLOBAL_SCOPE && isset($tokenInfo['scope']))
131 {
132 $tokenScope = explode(',', $tokenInfo['scope']);
133 $tokenScope = \Bitrix\Rest\Engine\RestManager::fillAlternativeScope($scope, $tokenScope);
134 if(!in_array($scope, $tokenScope))
135 {
136 $tokenInfo = array('error' => 'insufficient_scope', 'error_description' => 'The request requires higher privileges than provided by the access token');
137 $error = true;
138 }
139 }
140
141 if(!$error && $tokenInfo['user_id'] > 0)
142 {
143 global $USER;
144 if ($USER instanceof \CUser && $USER->isAuthorized())
145 {
146 if ((int)$USER->getId() !== (int)$tokenInfo['user_id'])
147 {
148 $tokenInfo = [
149 'error' => 'authorization_error',
150 'error_description' => Loc::getMessage('REST_OAUTH_ERROR_LOGOUT_BEFORE'),
151 ];
152 $error = true;
153 }
154 }
155 elseif (!\CRestUtil::makeAuth($tokenInfo))
156 {
157 $tokenInfo = array('error' => 'authorization_error', 'error_description' => 'Unable to authorize user');
158 $error = true;
159 }
160 elseif(!\CRestUtil::checkAppAccess($tokenInfo['client_id']))
161 {
162 $tokenInfo = array('error' => 'user_access_error', 'error_description' => 'The user does not have access to the application.');
163 $error = true;
164 }
165 }
166
167 $res = $tokenInfo;
168
169 $res['parameters_clear'] = static::$authQueryParams;
170 $res['auth_type'] = static::AUTH_TYPE;
171 $res['parameters_callback'] = array(__CLASS__, 'updateTokenParameters');
172
173 foreach(static::$authQueryAdditional as $key)
174 {
175 if(array_key_exists($key, $query))
176 {
177 $res[$key] = $query[$key];
178 $res['parameters_clear'][] = $key;
179 }
180 }
181
182 return !$error;
183 }
184
185 return false;
186 }
187
188 return null;
189 }
190
191 public static function getAuthKey(array $query)
192 {
193 $authKey = null;
194
195 $authHeader = \Bitrix\Main\Application::getInstance()->getContext()->getRequest()->getHeader('Authorization');
196 if($authHeader !== null)
197 {
198 if(preg_match('/^Bearer\s+/i', $authHeader))
199 {
200 $authKey = preg_replace('/^Bearer\s+/i', '', $authHeader);
201 }
202 }
203
204 if($authKey === null)
205 {
206 foreach(static::$authQueryParams as $key)
207 {
208 if(array_key_exists($key, $query) && !is_array($query[$key]))
209 {
210 $authKey = $query[$key];
211 break;
212 }
213 }
214 }
215
216 return $authKey;
217 }
218
219 public static function updateTokenParameters($tokenInfo)
220 {
221 $authResult = static::getStorage()->restore($tokenInfo['access_token']);
222
223 if(is_array($authResult))
224 {
225 if(!is_array($authResult['parameters']))
226 {
227 $authResult['parameters'] = array();
228 }
229
230 $authResult['parameters'] = array_replace_recursive($authResult['parameters'], $tokenInfo['parameters']);
231
232 static::getStorage()->rewrite($authResult);
233 }
234 }
235
236 protected static function check($accessToken)
237 {
238 $authResult = static::getStorage()->restore($accessToken);
239 if($authResult === false)
240 {
241 $client = OAuthService::getEngine()->getClient();
242 $tokenInfo = $client->checkAuth($accessToken);
243
244 if(is_array($tokenInfo))
245 {
246 if($tokenInfo['result'])
247 {
248 $authResult = $tokenInfo['result'];
249 $authResult['user_id'] = $authResult['parameters'][static::PARAM_LOCAL_USER];
250 unset($authResult['parameters'][static::PARAM_LOCAL_USER]);
251
252 // compatibility with old oauth response
253 if(!isset($authResult['expires']) && isset($authResult['expires_in']))
254 {
255 $authResult['expires'] = time() + $authResult['expires_in'];
256 }
257 }
258 else
259 {
260 $authResult = $tokenInfo;
261 $authResult['access_token'] = $accessToken;
262 }
263
264 static::getStorage()->store($authResult);
265 }
266 else
267 {
268 $authResult = ['access_token' => $accessToken];
269 }
270 }
271
272 return $authResult;
273 }
274
275 protected static function getTokenParams($additionalParams, $userId)
276 {
277 if(!is_array($additionalParams))
278 {
279 $additionalParams = array();
280 }
281
282 $additionalParams[static::PARAM_LOCAL_USER] = $userId;
283 $additionalParams[static::PARAM_TZ_OFFSET] = \CTimeZone::getOffset();
284 $additionalParams[Session::PARAM_SESSION] = Session::get();
285
286 return $additionalParams;
287 }
288
292 public static function getStorage()
293 {
294 if(static::$storage === null)
295 {
296 static::setStorage(new StorageCache());
297 }
298
299 return static::$storage;
300 }
301
305 public static function setStorage(AuthStorageInterface $storage)
306 {
307 static::$storage = $storage;
308 }
309}
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static $authQueryParams
Definition auth.php:24
static getByClientId($clientId)
Definition app.php:929
static is(string $type, string $code)
static isAvailableCount(string $entityType, $entity=0)
Definition access.php:110
static isAvailable($app='')
Definition access.php:65
static getTokenParams($additionalParams, $userId)
Definition auth.php:275
static setStorage(AuthStorageInterface $storage)
Definition auth.php:305
static updateTokenParameters($tokenInfo)
Definition auth.php:219
static check($accessToken)
Definition auth.php:236
static authorizeClient($clientId, $userId, $state='')
Definition auth.php:47
static storeRegisteredAuth(array $tokenInfo)
Definition auth.php:60
static $authQueryAdditional
Definition auth.php:40
static getAuthKey(array $query)
Definition auth.php:191
static getStorage()
Definition auth.php:292
static onRestCheckAuth(array $query, $scope, &$res)
Definition auth.php:65