Rick Watson
5 years ago
10 changed files with 222 additions and 135 deletions
-
52src/AsyncAuthJsonWebHandler.h
-
19src/AsyncJsonWebHandler.h
-
45src/AuthenticationService.cpp
-
30src/AuthenticationService.h
-
120src/SecurityManager.cpp
-
65src/SecurityManager.h
-
4src/SettingsPersistence.h
-
4src/SettingsService.h
-
6src/SimpleService.h
-
12src/main.cpp
@ -0,0 +1,52 @@ |
|||
#ifndef AsyncAuthJsonWebHandler_H_ |
|||
#define AsyncAuthJsonWebHandler_H_ |
|||
|
|||
#include <ESPAsyncWebServer.h> |
|||
#include <AsyncJsonWebHandler.h> |
|||
#include <ArduinoJson.h> |
|||
#include <SecurityManager.h> |
|||
|
|||
typedef std::function<void(AsyncWebServerRequest *request, JsonDocument &jsonDocument, Authentication &authentication)> AuthenticationJsonRequestCallback; |
|||
|
|||
/** |
|||
* Extends AsyncJsonWebHandler with a wrapper which verifies the user is authenticated. |
|||
* |
|||
* TODO - Extend with role checking support, possibly with a callback to verify the user. |
|||
*/ |
|||
class AsyncAuthJsonWebHandler: public AsyncJsonWebHandler { |
|||
|
|||
private: |
|||
SecurityManager *_securityManager; |
|||
using AsyncJsonWebHandler::onRequest; |
|||
|
|||
public: |
|||
|
|||
AsyncAuthJsonWebHandler() : |
|||
AsyncJsonWebHandler(), _securityManager(NULL) {} |
|||
|
|||
~AsyncAuthJsonWebHandler() {} |
|||
|
|||
void setSecurityManager(SecurityManager *securityManager) { |
|||
_securityManager = securityManager; |
|||
} |
|||
|
|||
void onRequest(AuthenticationJsonRequestCallback callback) { |
|||
AsyncJsonWebHandler::onRequest([this, callback](AsyncWebServerRequest *request, JsonDocument &jsonDocument) { |
|||
if(!_securityManager) { |
|||
Serial.print("Security manager not configured for endpoint: "); |
|||
Serial.println(_uri); |
|||
request->send(500); |
|||
return; |
|||
} |
|||
Authentication authentication = _securityManager->authenticateRequest(request); |
|||
if (!authentication.isAuthenticated()) { |
|||
request->send(401); |
|||
return; |
|||
} |
|||
callback(request, jsonDocument, authentication); |
|||
}); |
|||
} |
|||
|
|||
}; |
|||
|
|||
#endif // end AsyncAuthJsonWebHandler_H_ |
@ -0,0 +1,45 @@ |
|||
#include <AuthenticationService.h>
|
|||
|
|||
AuthenticationService::AuthenticationService(AsyncWebServer* server, SecurityManager* securityManager): |
|||
_server(server), _securityManager(securityManager) { |
|||
server->on(VERIFY_AUTHORIZATION_PATH, HTTP_GET, std::bind(&AuthenticationService::verifyAuthorization, this, std::placeholders::_1)); |
|||
|
|||
_signInHandler.setUri(SIGN_IN_PATH); |
|||
_signInHandler.setMethod(HTTP_POST); |
|||
_signInHandler.setMaxContentLength(MAX_SECURITY_MANAGER_SETTINGS_SIZE); |
|||
_signInHandler.onRequest(std::bind(&AuthenticationService::signIn, this, std::placeholders::_1, std::placeholders::_2)); |
|||
server->addHandler(&_signInHandler); |
|||
} |
|||
|
|||
AuthenticationService::~AuthenticationService() {} |
|||
|
|||
/**
|
|||
* Verifys that the request supplied a valid JWT. |
|||
*/ |
|||
void AuthenticationService::verifyAuthorization(AsyncWebServerRequest *request) { |
|||
Authentication authentication = _securityManager->authenticateRequest(request); |
|||
request->send(authentication.isAuthenticated() ? 200: 401); |
|||
} |
|||
|
|||
/**
|
|||
* Signs in a user if the username and password match. Provides a JWT to be used in the Authorization header in subsequent requests. |
|||
*/ |
|||
void AuthenticationService::signIn(AsyncWebServerRequest *request, JsonDocument &jsonDocument){ |
|||
if (jsonDocument.is<JsonObject>()) { |
|||
String username = jsonDocument["username"]; |
|||
String password = jsonDocument["password"]; |
|||
Authentication authentication = _securityManager->authenticate(username, password); |
|||
if (authentication.isAuthenticated()) { |
|||
User* user = authentication.getUser(); |
|||
AsyncJsonResponse * response = new AsyncJsonResponse(MAX_USERS_SIZE); |
|||
JsonObject jsonObject = response->getRoot(); |
|||
jsonObject["access_token"] = _securityManager->generateJWT(user); |
|||
response->setLength(); |
|||
request->send(response); |
|||
return; |
|||
} |
|||
} |
|||
AsyncWebServerResponse *response = request->beginResponse(401); |
|||
request->send(response); |
|||
} |
|||
|
@ -0,0 +1,30 @@ |
|||
#ifndef AuthenticationService_H_ |
|||
#define AuthenticationService_H_ |
|||
|
|||
#include <SecurityManager.h> |
|||
|
|||
#define VERIFY_AUTHORIZATION_PATH "/rest/verifyAuthorization" |
|||
#define SIGN_IN_PATH "/rest/signIn" |
|||
|
|||
#define MAX_AUTHENTICATION_SIZE 256 |
|||
|
|||
class AuthenticationService { |
|||
|
|||
public: |
|||
|
|||
AuthenticationService(AsyncWebServer* server, SecurityManager* securityManager) ; |
|||
~AuthenticationService(); |
|||
|
|||
private: |
|||
// server instance |
|||
AsyncWebServer* _server; |
|||
SecurityManager* _securityManager; |
|||
AsyncJsonWebHandler _signInHandler; |
|||
|
|||
// endpoint functions |
|||
void signIn(AsyncWebServerRequest *request, JsonDocument &jsonDocument); |
|||
void verifyAuthorization(AsyncWebServerRequest *request); |
|||
|
|||
}; |
|||
|
|||
#endif // end SecurityManager_h |
Write
Preview
Loading…
Cancel
Save
Reference in new issue