Completed
Push — master ( 78c95b...78d54b )
by Dmitry
12:13
created

HttpBasicAuth::authenticate()   D

Complexity

Conditions 9
Paths 10

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 9

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 16
cts 16
cp 1
rs 4.909
c 0
b 0
f 0
cc 9
eloc 16
nc 10
nop 3
crap 9
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\filters\auth;
9
10
/**
11
 * HttpBasicAuth is an action filter that supports the HTTP Basic authentication method.
12
 *
13
 * You may use HttpBasicAuth by attaching it as a behavior to a controller or module, like the following:
14
 *
15
 * ```php
16
 * public function behaviors()
17
 * {
18
 *     return [
19
 *         'basicAuth' => [
20
 *             'class' => \yii\filters\auth\HttpBasicAuth::className(),
21
 *         ],
22
 *     ];
23
 * }
24
 * ```
25
 *
26
 * The default implementation of HttpBasicAuth uses the [[\yii\web\User::loginByAccessToken()|loginByAccessToken()]]
27
 * method of the `user` application component and only passes the user name. This implementation is used
28
 * for authenticating API clients.
29
 *
30
 * If you want to authenticate users using username and password, you should provide the [[auth]] function for example like the following:
31
 *
32
 * ```php
33
 * public function behaviors()
34
 * {
35
 *     return [
36
 *         'basicAuth' => [
37
 *             'class' => \yii\filters\auth\HttpBasicAuth::className(),
38
 *             'auth' => function ($username, $password) {
39
 *                 $user = User::find()->where(['username' => $username])->one();
40
 *                 if ($user->verifyPassword($password)) {
41
 *                     return $user;
42
 *                 }
43
 *                 return null;
44
 *             },
45
 *         ],
46
 *     ];
47
 * }
48
 * ```
49
 *
50
 * > Tip: In case authentication does not work like expected, make sure your web server passes
51
 * username and password to `$_SERVER['PHP_AUTH_USER']` and `$_SERVER['PHP_AUTH_PW']` variables.
52
 * If you are using Apache with PHP-CGI, you might need to add this line to your `.htaccess` file:
53
 * ```
54
 * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
55
 * ```
56
 *
57
 * @author Qiang Xue <[email protected]>
58
 * @since 2.0
59
 */
60
class HttpBasicAuth extends AuthMethod
61
{
62
    /**
63
     * @var string the HTTP authentication realm
64
     */
65
    public $realm = 'api';
66
    /**
67
     * @var callable a PHP callable that will authenticate the user with the HTTP basic auth information.
68
     * The callable receives a username and a password as its parameters. It should return an identity object
69
     * that matches the username and password. Null should be returned if there is no such identity.
70
     * The callable will be called only if current user is not authenticated.
71
     *
72
     * The following code is a typical implementation of this callable:
73
     *
74
     * ```php
75
     * function ($username, $password) {
76
     *     return \app\models\User::findOne([
77
     *         'username' => $username,
78
     *         'password' => $password,
79
     *     ]);
80
     * }
81
     * ```
82
     *
83
     * If this property is not set, the username information will be considered as an access token
84
     * while the password information will be ignored. The [[\yii\web\User::loginByAccessToken()]]
85
     * method will be called to authenticate and login the user.
86
     */
87
    public $auth;
88
89
90
    /**
91
     * {@inheritdoc}
92
     */
93 25
    public function authenticate($user, $request, $response)
94
    {
95 25
        list($username, $password) = $request->getAuthCredentials();
96
97 25
        if ($this->auth) {
98 10
            if ($username !== null || $password !== null) {
99 10
                $identity = $user->getIdentity() ?: call_user_func($this->auth, $username, $password);
100
101 10
                if ($identity === null) {
102 4
                    $this->handleFailure($response);
103 6
                } elseif ($user->getIdentity(false) !== $identity) {
104 3
                    $user->switchIdentity($identity);
105
                }
106
107 6
                return $identity;
108
            }
109 15
        } elseif ($username !== null) {
110 12
            $identity = $user->loginByAccessToken($username, get_class($this));
111 12
            if ($identity === null) {
112 3
                $this->handleFailure($response);
113
            }
114
115 9
            return $identity;
116
        }
117
118 3
        return null;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124 3
    public function challenge($response)
125
    {
126 3
        $response->getHeaders()->set('WWW-Authenticate', "Basic realm=\"{$this->realm}\"");
127 3
    }
128
}
129