Fork of the excellent esp8266-react - https://github.com/rjwats/esp8266-react
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
2.3 KiB

  1. #include <SecurityManager.h>
  2. Authentication SecurityManager::authenticateRequest(AsyncWebServerRequest *request) {
  3. AsyncWebHeader* authorizationHeader = request->getHeader(AUTHORIZATION_HEADER);
  4. if (authorizationHeader) {
  5. String value = authorizationHeader->value();
  6. if (value.startsWith(AUTHORIZATION_HEADER_PREFIX)){
  7. value = value.substring(AUTHORIZATION_HEADER_PREFIX_LEN);
  8. return authenticateJWT(value);
  9. }
  10. }
  11. return Authentication();
  12. }
  13. Authentication SecurityManager::authenticateJWT(String jwt) {
  14. DynamicJsonDocument payloadDocument(MAX_JWT_SIZE);
  15. _jwtHandler.parseJWT(jwt, payloadDocument);
  16. if (payloadDocument.is<JsonObject>()) {
  17. JsonObject parsedPayload = payloadDocument.as<JsonObject>();
  18. String username = parsedPayload["username"];
  19. for (User _user : _users) {
  20. if (_user.getUsername() == username && validatePayload(parsedPayload, &_user)){
  21. return Authentication(_user);
  22. }
  23. }
  24. }
  25. return Authentication();
  26. }
  27. Authentication SecurityManager::authenticate(String username, String password) {
  28. for (User _user : _users) {
  29. if (_user.getUsername() == username && _user.getPassword() == password){
  30. return Authentication(_user);
  31. }
  32. }
  33. return Authentication();
  34. }
  35. inline void populateJWTPayload(JsonObject &payload, User *user) {
  36. payload["username"] = user->getUsername();
  37. payload["admin"] = user -> isAdmin();
  38. }
  39. boolean SecurityManager::validatePayload(JsonObject &parsedPayload, User *user) {
  40. DynamicJsonDocument _jsonDocument(MAX_JWT_SIZE);
  41. JsonObject payload = _jsonDocument.to<JsonObject>();
  42. populateJWTPayload(payload, user);
  43. return payload == parsedPayload;
  44. }
  45. String SecurityManager::generateJWT(User *user) {
  46. DynamicJsonDocument _jsonDocument(MAX_JWT_SIZE);
  47. JsonObject payload = _jsonDocument.to<JsonObject>();
  48. populateJWTPayload(payload, user);
  49. return _jwtHandler.buildJWT(payload);
  50. }
  51. ArRequestHandlerFunction SecurityManager::wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate) {
  52. return [this, onRequest, predicate](AsyncWebServerRequest *request){
  53. Authentication authentication = authenticateRequest(request);
  54. if (!predicate(authentication)) {
  55. request->send(401);
  56. return;
  57. }
  58. onRequest(request);
  59. };
  60. }