Update to version 3.9.6
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||
// Copyright 2016-2026 Hristo Gochkov, Mathieu Carbou, Emil Muratov, Will Miles
|
||||
|
||||
//
|
||||
// Authentication and authorization middlewares
|
||||
@@ -29,30 +29,36 @@ static AsyncAuthenticationMiddleware basicAuthHash;
|
||||
static AsyncAuthenticationMiddleware digestAuth;
|
||||
static AsyncAuthenticationMiddleware digestAuthHash;
|
||||
|
||||
static AsyncAuthenticationMiddleware bearerAuthSharedKey;
|
||||
static AsyncAuthenticationMiddleware bearerAuthJWT;
|
||||
|
||||
// complex authentication which adds request attributes for the next middlewares and handler
|
||||
static AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest *request, ArMiddlewareNext next) {
|
||||
if (!request->authenticate("user", "password")) {
|
||||
if (request->authenticate("Mathieu", "password")) {
|
||||
request->setAttribute("user", "Mathieu");
|
||||
} else if (request->authenticate("Bob", "password")) {
|
||||
request->setAttribute("user", "Bob");
|
||||
} else {
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
|
||||
// add attributes to the request for the next middlewares and handler
|
||||
request->setAttribute("user", "Mathieu");
|
||||
request->setAttribute("role", "staff");
|
||||
if (request->hasParam("token")) {
|
||||
request->setAttribute("token", request->getParam("token")->value().c_str());
|
||||
if (request->getAttribute("user") == "Mathieu") {
|
||||
request->setAttribute("role", "staff");
|
||||
} else {
|
||||
request->setAttribute("role", "user");
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
static AsyncAuthorizationMiddleware authz([](AsyncWebServerRequest *request) {
|
||||
return request->getAttribute("token") == "123";
|
||||
return request->getAttribute("role") == "staff";
|
||||
});
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
#if SOC_WIFI_SUPPORTED || CONFIG_ESP_WIFI_REMOTE_ENABLED || LT_ARD_HAS_WIFI
|
||||
#if ASYNCWEBSERVER_WIFI_SUPPORTED
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAP("esp-captive");
|
||||
#endif
|
||||
@@ -87,6 +93,36 @@ void setup() {
|
||||
digestAuthHash.setAuthFailureMessage("Authentication failed");
|
||||
digestAuthHash.setAuthType(AsyncAuthType::AUTH_DIGEST);
|
||||
|
||||
// bearer authentication with shared key
|
||||
bearerAuthSharedKey.setAuthType(AsyncAuthType::AUTH_BEARER);
|
||||
bearerAuthSharedKey.setToken("shared-secret-key");
|
||||
|
||||
// bearer authentication with a JWT token
|
||||
bearerAuthJWT.setAuthType(AsyncAuthType::AUTH_BEARER);
|
||||
bearerAuthJWT.setAuthentificationFunction([](AsyncWebServerRequest *request) {
|
||||
const String &token = request->authChallenge();
|
||||
// 1. decode base64 token
|
||||
// 2. decrypt token
|
||||
const String &decrypted = "..."; // TODO
|
||||
// 3. validate token (check signature, expiration, etc)
|
||||
bool valid = token == "<token>" || token == "<another token>";
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
// 4. extract user info from token and set request attributes
|
||||
if (token == "<token>") {
|
||||
request->setAttribute("user", "Mathieu");
|
||||
request->setAttribute("role", "staff");
|
||||
return true; // return true if token is valid, false otherwise
|
||||
}
|
||||
if (token == "<another token>") {
|
||||
request->setAttribute("user", "Bob");
|
||||
request->setAttribute("role", "user");
|
||||
return true; // return true if token is valid, false otherwise
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// basic authentication method
|
||||
// curl -v -u admin:admin http://192.168.4.1/auth-basic
|
||||
server
|
||||
@@ -132,9 +168,9 @@ void setup() {
|
||||
.addMiddleware(&digestAuthHash);
|
||||
|
||||
// test digest auth custom authorization middleware
|
||||
// curl -v --digest -u user:password http://192.168.4.1/auth-custom?token=123 => OK
|
||||
// curl -v --digest -u user:password http://192.168.4.1/auth-custom?token=456 => 403
|
||||
// curl -v --digest -u user:FAILED http://192.168.4.1/auth-custom?token=456 => 401
|
||||
// curl -v --digest -u Mathieu:password http://192.168.4.1/auth-custom => OK
|
||||
// curl -v --digest -u Bob:password http://192.168.4.1/auth-custom => 403
|
||||
// curl -v --digest -u any:password http://192.168.4.1/auth-custom => 401
|
||||
server
|
||||
.on(
|
||||
"/auth-custom", HTTP_GET,
|
||||
@@ -148,6 +184,32 @@ void setup() {
|
||||
)
|
||||
.addMiddlewares({&complexAuth, &authz});
|
||||
|
||||
// Bearer authentication with a shared key
|
||||
// curl -v -H "Authorization: Bearer shared-secret-key" http://192.168.4.1/auth-bearer-shared-key => OK
|
||||
server
|
||||
.on(
|
||||
"/auth-bearer-shared-key", HTTP_GET,
|
||||
[](AsyncWebServerRequest *request) {
|
||||
request->send(200, "text/plain", "Hello, world!");
|
||||
}
|
||||
)
|
||||
.addMiddleware(&bearerAuthSharedKey);
|
||||
|
||||
// Bearer authentication with a JWT token
|
||||
// curl -v -H "Authorization: Bearer <token>" http://192.168.4.1/auth-bearer-jwt => OK
|
||||
// curl -v -H "Authorization: Bearer <another token>" http://192.168.4.1/auth-bearer-jwt => 403 Forbidden
|
||||
// curl -v -H "Authorization: Bearer invalid-token" http://192.168.4.1/auth-bearer-jwt => 401 Unauthorized
|
||||
server
|
||||
.on(
|
||||
"/auth-bearer-jwt", HTTP_GET,
|
||||
[](AsyncWebServerRequest *request) {
|
||||
Serial.println("User: " + request->getAttribute("user"));
|
||||
Serial.println("Role: " + request->getAttribute("role"));
|
||||
request->send(200, "text/plain", "Hello, world!");
|
||||
}
|
||||
)
|
||||
.addMiddlewares({&bearerAuthJWT, &authz});
|
||||
|
||||
server.begin();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user