/
auth.php
73 lines (64 loc) · 2.42 KB
/
auth.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
<?php
use lithium\security\Auth;
use app\models\Users;
Auth::config(array(
'default' => array(
'adapter' => 'Form',
'model' => 'Users',
'fields' => array('username', 'password')
)
));
/**
* Filter calls to `Auth::check()` and if the `HTTP_X_USERNAME' and `HTTP_X_SIGNATURE`
* headers are sent use this to either verify the request or throw a no-access exception
*
* We use **url** + either query string *OR* POST fields for GET and POST respectively
* to generate a new signature on our side, if this signature matches the one that is passed
* we consider the request as a valid request for that username
*/
Auth::applyFilter('check', function($self, $params, $chain)
{
$result = $chain->next($self, $params, $chain);
/**
* `Auth::check` is called in two context
* 1. With a `Request` object to sign a user in
* 2. With no arguments to check if the current user is signed in
*
* We only need to check in the first case.
*/
if (isset($params['credentials']) && $params['credentials']) {
$request = $params['credentials'];
$signature = $request->env('HTTP_X_SIGNATURE');
$username = $request->env('HTTP_X_USERNAME');
if ($username && $signature) {
/**
* Find the username the request is attempted to be made for
* The user object is needed because it holds the secret key
* we need to be able to regenerate the signature
*/
$user = Users::first(array('conditions' => compact('username')));
if (!$user) {
throw new \Exception("Invalid user $username");
}
/**
* GET and POST/PUT passes payload differently, this either `query` or `data`
* Also doing rewriting can mean that the `url` GET param is added
*/
$signData = $request->is('get')
? array_diff_key($request->query, array('url' => 'sodoff'))
: $request->data;
/**
* Prepend the request path so all requests with no data
* does not get the same key
*/
array_unshift($signData, $request->env('base'));
if ($signature === $user->sign($signData)) {
return true;
}
else {
throw new \Exception("Signature match failed in signed request");
}
}
}
return $result;
});