Commit f932b53a authored by François Agneray's avatar François Agneray

Add authorization middleware to handle jwt

parent ba5e6fcd
......@@ -179,8 +179,3 @@ $container->set('App\Action\SearchAction', function (ContainerInterface $c) {
$container->set('App\Action\DownloadFileAction', function (ContainerInterface $c) {
return new App\Action\DownloadFileAction($c->get('em'));
});
// Middlewares
$container->set('App\Middleware\AuthorizationMiddleware', function (ContainerInterface $c) {
return new App\Middleware\AuthorizationMiddleware($c->get('em'), $c->get(SETTINGS)['token_options']);
});
......@@ -14,3 +14,4 @@ $app->add(new App\Middleware\JsonBodyParserMiddleware());
$app->add(new App\Middleware\ContentTypeJsonMiddleware());
$app->add(new App\Middleware\CorsMiddleware());
$app->add(new App\Middleware\MetamodelSqlLoggerMiddleware($container->get('logger'), $container->get('em')));
$app->add(new App\Middleware\AuthorizationMiddleware($container->get(SETTINGS)['token']));
......@@ -29,5 +29,9 @@ return [
'name' => getenv('LOGGER_NAME'),
'path' => getenv('LOGGER_PATH'),
'level' => getenv('LOGGER_LEVEL')
],
'token' => [
'issuer' => getenv('TOKEN_ISSUER'),
'public_key_file' => getenv('TOKEN_PUBLIC_KEY_FILE')
]
];
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "41b0ad136ffb7b6f8f4c93825e72e5be",
"content-hash": "9f060118c163df9ee6fc4a2bb7d5c005",
"packages": [
{
"name": "doctrine/annotations",
......@@ -900,6 +900,7 @@
"keywords": [
"reflection"
],
"abandoned": "roave/better-reflection",
"time": "2018-06-14T14:45:07+00:00"
},
{
......@@ -958,8 +959,74 @@
"serialize",
"tokenizer"
],
"abandoned": "opis/closure",
"time": "2018-03-21T22:21:57+00:00"
},
{
"name": "lcobucci/jwt",
"version": "3.3.3",
"source": {
"type": "git",
"url": "https://github.com/lcobucci/jwt.git",
"reference": "c1123697f6a2ec29162b82f170dd4a491f524773"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/c1123697f6a2ec29162b82f170dd4a491f524773",
"reference": "c1123697f6a2ec29162b82f170dd4a491f524773",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-openssl": "*",
"php": "^5.6 || ^7.0"
},
"require-dev": {
"mikey179/vfsstream": "~1.5",
"phpmd/phpmd": "~2.2",
"phpunit/php-invoker": "~1.1",
"phpunit/phpunit": "^5.7 || ^7.3",
"squizlabs/php_codesniffer": "~2.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
}
},
"autoload": {
"psr-4": {
"Lcobucci\\JWT\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Luís Otávio Cobucci Oblonczyk",
"email": "lcobucci@gmail.com",
"role": "Developer"
}
],
"description": "A simple library to work with JSON Web Token and JSON Web Signature",
"keywords": [
"JWS",
"jwt"
],
"funding": [
{
"url": "https://github.com/lcobucci",
"type": "github"
},
{
"url": "https://www.patreon.com/lcobucci",
"type": "patreon"
}
],
"time": "2020-08-20T13:22:28+00:00"
},
{
"name": "monolog/monolog",
"version": "2.0.1",
......@@ -3620,5 +3687,6 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
"platform-dev": [],
"plugin-api-version": "1.1.0"
}
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh4woW+Tg4L3iGG9osCLi
1TD6vX/fAqX3iMfe9hi+M269FcGCl/1+Ls4gwLs/TqqFpWmg3T3bLuShHkabeGi5
CKr8hrHJMPA0NjPHuH1RUL/QyQpPgKQkmKxyUH9i3hdQtB2REcVZBmB5+JRIcUeh
cTLkpOWrRz9cquv8R7N8xD6OpdLWSFItYnOrKlR4II6EQaY0PBDyNQElXIiqTMLt
aTbXVn1suzT0NUwDTIvcxKpqTCEyM3meuIFsc+ISjff12WY5rLWoadVZHLwkfe/9
7zF3UYPb3ddZkQ/W3jQXYYMVgMHOfskXjstqH9XPkez4ovJUHukPYKsvvWWqiDCo
rwIDAQAB
-----END PUBLIC KEY-----
......@@ -17,6 +17,8 @@ services:
LOGGER_NAME: "anis-metamodel"
LOGGER_PATH: "php://stderr"
LOGGER_LEVEL: "debug"
TOKEN_ISSUER: http://localhost:8180/auth/realms/anis
TOKEN_PUBLIC_KEY_FILE: /data/public_key
ports:
- 8080:80
volumes:
......@@ -24,6 +26,7 @@ services:
- ./conf-dev/dev-php.ini:/usr/local/etc/php/conf.d/dev-php.ini
- ./conf-dev/vhost.conf:/etc/apache2/sites-available/000-default.conf
- ./conf-dev/data-dev:/data/ASPIC
- ./conf-dev/public_key:/data/public_key
keycloak:
image: jboss/keycloak
......
<?php
/*
* This file is part of Anis Server.
*
* (c) Laboratoire d'Astrophysique de Marseille / CNRS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Nyholm\Psr7\Response as NyholmResponse;
use Psr\Http\Server\MiddlewareInterface;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
/**
* Middleware to handle Authorization request header (JWT)
*
* @author François Agneray <francois.agneray@lam.fr>
* @package App\Middleware
*/
final class AuthorizationMiddleware implements MiddlewareInterface
{
/**
* Contains settings to handle Json Web Token
*
* @var array
*/
private $settings;
/**
* Create the classe before call process to execute this middleware
*
* @param array $settings Settings about token
*/
public function __construct(array $settings)
{
$this->settings = $settings;
}
/**
* Try to validating and verifing the signature of the json web token
* if Authorization header is present
*
* @param ServerRequest $request PSR-7 request
* @param RequestHandler $handler PSR-15 request handler
*
* @return Response
*/
public function process(Request $request, RequestHandler $handler): Response
{
if ($request->getMethod() === OPTIONS || !$request->hasHeader('Authorization')) {
return $handler->handle($request);
}
// Get token string from Authorizarion header
$bearer = $request->getHeader('Authorization');
$data = explode(' ', $bearer[0]);
if ($data[0] !== 'Bearer') {
return (new NyholmResponse())->withStatus(401);
}
// Parse the JWT Token
$token = (new Parser())->parse((string) $data[1]);
// Validating token (verifying expiration date and issuer)
$data = new ValidationData();
$data->setIssuer($this->settings['issuer']);
if (!$token->validate($data)) {
return (new NyholmResponse())->withStatus(401);
}
// Test token signature with the public key
$publicKey = new Key('file://' . $this->settings['public_key_file']);
if (!$token->verify(new Sha256(), $publicKey)) {
return (new NyholmResponse())->withStatus(401);
}
return $handler->handle($request->withAttribute('email', $token->getClaim('email')));
}
}
<?php
/*
* This file is part of Anis Auth.
* This file is part of Anis Server.
*
* (c) Laboratoire d'Astrophysique de Marseille / CNRS
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment