Skip to content

Commit e139908

Browse files
committed
Add Token authentication.
1 parent a819fb1 commit e139908

8 files changed

Lines changed: 56 additions & 6 deletions

File tree

API.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ Sono attualmente in sviluppo delle API REST per CAPS, che vengono usate
44
da (buona parte) del codice Javascript e in particolare la parte di
55
interfaccia utente sviluppata in React.
66

7+
## Autenticazione amministrativa con token
8+
9+
Se l'istanza configura `CAPS_ADMIN_TOKEN` e `CAPS_ADMIN_TOKEN_USER`, tutte le
10+
API possono essere invocate con privilegi amministrativi passando il token
11+
nell'header HTTP `Authorization`:
12+
13+
```http
14+
Authorization: Bearer <CAPS_ADMIN_TOKEN>
15+
```
16+
17+
`CAPS_ADMIN_TOKEN_USER` deve essere lo username di un utente già presente nel
18+
database. L'utente viene usato per attribuire operazioni, log e record creati;
19+
i privilegi amministrativi sono applicati soltanto alla richiesta autenticata
20+
dal token. Il token non viene accettato nella query string e deve essere usato
21+
esclusivamente tramite HTTPS.
22+
723
## Metodi disponibili
824

925
I Controller sono in `backend/src/Controller/Api/v1/` e i vari endpoint supportano i metodi HTTP GET, POST, PATCH e DELETE.

backend/config/app.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@
6060
'readonly' => env('CAPS_READONLY', '')
6161
],
6262

63+
// Optional instance-wide Bearer token. Both values must be set to enable it.
64+
// The username must identify an existing user, used for ownership and logs.
65+
'AdminToken' => [
66+
'token' => env('CAPS_ADMIN_TOKEN', ''),
67+
'username' => env('CAPS_ADMIN_TOKEN_USER', ''),
68+
],
69+
6370
'UnipiAuthenticate' => [
6471
'microsoft_oauth2_appid' => '',
6572
'microsoft_oauth2_client_secret' => '',

backend/example.env

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ CAPS_CDS='Testing'
3232
# default:
3333
# READONLY=''
3434

35+
# Optional administrator Bearer token. Both variables are required and the
36+
# configured user must already exist in CAPS.
37+
# CAPS_ADMIN_TOKEN='replace-with-a-long-random-token'
38+
# CAPS_ADMIN_TOKEN_USER='admin'
39+
3540
# Connection information used by the ORM to connect
3641
# to your application's datastores.
3742
#
@@ -104,4 +109,3 @@ CAPS_CDS='Testing'
104109
# for more information.
105110
#
106111
# MAIL_FROM='you@localhost'
107-

backend/src/Application.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323
namespace App;
2424

25+
use App\Authentication\Authenticator\AdminTokenAuthenticator;
2526
use App\Identifier\Resolver\UnipiResolver;
2627
use Authentication\AuthenticationService;
2728
use Authentication\AuthenticationServiceInterface;
@@ -109,8 +110,12 @@ public function middleware($middlewareQueue): \Cake\Http\MiddlewareQueue
109110
'cacheTime' => Configure::read('Asset.cacheTime')
110111
]))
111112

112-
// Add CSRF protection
113-
->add(new SessionCsrfProtectionMiddleware())
113+
// Add CSRF protection. Stateless Bearer-token requests are exempt.
114+
->add((new SessionCsrfProtectionMiddleware())->skipCheckCallback(
115+
function (ServerRequestInterface $request): bool {
116+
return AdminTokenAuthenticator::matchesRequest($request);
117+
}
118+
))
114119

115120
// Add routing middleware.
116121
// If you have a large number of routes connected, turning on routes
@@ -160,7 +165,10 @@ public function getAuthenticationService(ServerRequestInterface $request) : Auth
160165
IdentifierInterface::CREDENTIAL_PASSWORD => 'password'
161166
];
162167

163-
// Load the authenticators. Session should be first.
168+
// The administrator token takes precedence over an existing session.
169+
$service->loadAuthenticator(AdminTokenAuthenticator::class);
170+
171+
// Load the remaining authenticators.
164172
$service->loadAuthenticator('Authentication.Session');
165173
$service->loadAuthenticator('Authentication.Form', [
166174
'fields' => $fields,

docker/app.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
'readonly' => ('@CAPS_READONLY@' == '') ? false : '@CAPS_READONLY@'
3535
],
3636

37+
'AdminToken' => [
38+
'token' => env('CAPS_ADMIN_TOKEN', ''),
39+
'username' => env('CAPS_ADMIN_TOKEN_USER', ''),
40+
],
41+
3742
'UnipiAuthenticate' => [
3843
'microsoft_oauth2_appid' => '@MICROSOFT_OAUTH2_APPID@',
3944
'microsoft_oauth2_client_secret' => '@MICROSOFT_OAUTH2_CLIENT_SECRET@',

docker/caps.env.template

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ CAPS_CDS=Matematica
4747
# string, that will be displayed to the user.
4848
# CAPS_READONLY=Read-only mode enabled
4949

50+
# Optional administrator Bearer token. Both variables are required and the
51+
# configured user must already exist in CAPS. Generate a token with:
52+
# openssl rand -hex 32
53+
# CAPS_ADMIN_TOKEN=replace-with-a-long-random-token
54+
# CAPS_ADMIN_TOKEN_USER=admin
55+
5056
# Username for the mysql user for CAPS. Should match CAPS_DB_USERNAME
5157
# if using the combined docker-compose setup
5258
MYSQL_USER=caps
@@ -77,4 +83,3 @@ OAUTH2_CLIENT_SECRET=
7783
OAUTH2_URL_AUTHORIZE=https://iam.unipi.it/oauth2/authorize
7884
OAUTH2_URL_TOKEN=https://iam.unipi.it/oauth2/token
7985
OAUTH2_URL_USERINFO=https://iam.unipi.it/oauth2/userinfo
80-

docker/docker-compose-dev.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ services:
1616
- "../backend/src:/backend/src:ro"
1717
- "../backend/templates:/backend/templates:ro"
1818
- "../backend/webroot:/backend/webroot:ro"
19+
- "../backend/config/app.php:/backend/config/app.php:ro"
1920
- "../backend/config/Migrations:/backend/config/Migrations"
2021
- "../backend/config/routes.php:/backend/config/routes.php"
2122
- "./logs:/backend/logs"

example.env

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ CAPS_USERS_PASSWD="admin:admin,user:user"
5151
# CAPS_ADMIN=''
5252
CAPS_ADMINS='admin'
5353

54+
# Optional administrator Bearer token. The user must already exist in CAPS.
55+
# Generate a token with: openssl rand -hex 32
56+
# CAPS_ADMIN_TOKEN='replace-with-a-long-random-token'
57+
# CAPS_ADMIN_TOKEN_USER='admin'
58+
5459
# Connection information used by the ORM to connect
5560
# to your application's datastores.
5661
#
@@ -124,4 +129,3 @@ CAPS_DB_DATABASE=caps.sqlite
124129
# for more information.
125130
#
126131
# MAIL_FROM=you@localhost
127-

0 commit comments

Comments
 (0)