aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVirtualTam <virtualtam@flibidi.net>2017-01-07 22:23:47 +0100
committerVirtualTam <virtualtam+github@flibidi.net>2017-01-15 13:41:04 +0100
commit63ef549749fac9d0e302842f06e7794d1daabc13 (patch)
tree0ff9dc942d61ca50a251a900f1b923ac8ff39cda
parent37ab940599d40472c5b4a3bbe5a10515046c64ee (diff)
downloadShaarli-63ef549749fac9d0e302842f06e7794d1daabc13.tar.gz
Shaarli-63ef549749fac9d0e302842f06e7794d1daabc13.tar.zst
Shaarli-63ef549749fac9d0e302842f06e7794d1daabc13.zip
API: expect JWT in the Authorization header
Relates to https://github.com/shaarli/Shaarli/pull/731 Added: - require the presence of the 'Authorization' header Changed: - use the HTTP Bearer Token authorization schema See: - https://jwt.io/introduction/#how-do-json-web-tokens-work- - https://tools.ietf.org/html/rfc6750 - http://security.stackexchange.com/q/108662 Signed-off-by: VirtualTam <virtualtam@flibidi.net>
-rw-r--r--application/api/ApiMiddleware.php11
-rw-r--r--tests/api/ApiMiddlewareTest.php29
2 files changed, 34 insertions, 6 deletions
diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php
index 162e88e0..522091ca 100644
--- a/application/api/ApiMiddleware.php
+++ b/application/api/ApiMiddleware.php
@@ -98,8 +98,7 @@ class ApiMiddleware
98 * @throws ApiAuthorizationException The token couldn't be validated. 98 * @throws ApiAuthorizationException The token couldn't be validated.
99 */ 99 */
100 protected function checkToken($request) { 100 protected function checkToken($request) {
101 $jwt = $request->getHeaderLine('jwt'); 101 if (! $request->hasHeader('Authorization')) {
102 if (empty($jwt)) {
103 throw new ApiAuthorizationException('JWT token not provided'); 102 throw new ApiAuthorizationException('JWT token not provided');
104 } 103 }
105 104
@@ -107,7 +106,13 @@ class ApiMiddleware
107 throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration'); 106 throw new ApiAuthorizationException('Token secret must be set in Shaarli\'s administration');
108 } 107 }
109 108
110 ApiUtils::validateJwtToken($jwt, $this->conf->get('api.secret')); 109 $authorization = $request->getHeaderLine('Authorization');
110
111 if (! preg_match('/^Bearer (.*)/i', $authorization, $matches)) {
112 throw new ApiAuthorizationException('Invalid JWT header');
113 }
114
115 ApiUtils::validateJwtToken($matches[1], $this->conf->get('api.secret'));
111 } 116 }
112 117
113 /** 118 /**
diff --git a/tests/api/ApiMiddlewareTest.php b/tests/api/ApiMiddlewareTest.php
index 4d4dd9b9..d9753b1d 100644
--- a/tests/api/ApiMiddlewareTest.php
+++ b/tests/api/ApiMiddlewareTest.php
@@ -143,7 +143,7 @@ class ApiMiddlewareTest extends \PHPUnit_Framework_TestCase
143 $env = Environment::mock([ 143 $env = Environment::mock([
144 'REQUEST_METHOD' => 'GET', 144 'REQUEST_METHOD' => 'GET',
145 'REQUEST_URI' => '/echo', 145 'REQUEST_URI' => '/echo',
146 'HTTP_JWT'=> 'jwt', 146 'HTTP_AUTHORIZATION'=> 'Bearer jwt',
147 ]); 147 ]);
148 $request = Request::createFromEnvironment($env); 148 $request = Request::createFromEnvironment($env);
149 $response = new Response(); 149 $response = new Response();
@@ -157,7 +157,30 @@ class ApiMiddlewareTest extends \PHPUnit_Framework_TestCase
157 } 157 }
158 158
159 /** 159 /**
160 * Invoke the middleware without an invalid JWT token (debug): 160 * Invoke the middleware with an invalid JWT token header
161 */
162 public function testInvalidJwtAuthHeaderDebug()
163 {
164 $this->conf->set('dev.debug', true);
165 $mw = new ApiMiddleware($this->container);
166 $env = Environment::mock([
167 'REQUEST_METHOD' => 'GET',
168 'REQUEST_URI' => '/echo',
169 'HTTP_AUTHORIZATION'=> 'PolarBearer jwt',
170 ]);
171 $request = Request::createFromEnvironment($env);
172 $response = new Response();
173 /** @var Response $response */
174 $response = $mw($request, $response, null);
175
176 $this->assertEquals(401, $response->getStatusCode());
177 $body = json_decode((string) $response->getBody());
178 $this->assertEquals('Not authorized: Invalid JWT header', $body->message);
179 $this->assertContains('ApiAuthorizationException', $body->stacktrace);
180 }
181
182 /**
183 * Invoke the middleware with an invalid JWT token (debug):
161 * should return a 401 error Unauthorized - with a specific message and a stacktrace. 184 * should return a 401 error Unauthorized - with a specific message and a stacktrace.
162 * 185 *
163 * Note: specific JWT errors tests are handled in ApiUtilsTest. 186 * Note: specific JWT errors tests are handled in ApiUtilsTest.
@@ -169,7 +192,7 @@ class ApiMiddlewareTest extends \PHPUnit_Framework_TestCase
169 $env = Environment::mock([ 192 $env = Environment::mock([
170 'REQUEST_METHOD' => 'GET', 193 'REQUEST_METHOD' => 'GET',
171 'REQUEST_URI' => '/echo', 194 'REQUEST_URI' => '/echo',
172 'HTTP_JWT'=> 'bad jwt', 195 'HTTP_AUTHORIZATION'=> 'Bearer jwt',
173 ]); 196 ]);
174 $request = Request::createFromEnvironment($env); 197 $request = Request::createFromEnvironment($env);
175 $response = new Response(); 198 $response = new Response();