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.

109 lines
2.4 KiB

  1. #ifndef SecurityManager_h
  2. #define SecurityManager_h
  3. #include <ArduinoJsonJWT.h>
  4. #include <ESPAsyncWebServer.h>
  5. #include <list>
  6. #define DEFAULT_JWT_SECRET "esp8266-react"
  7. #define AUTHORIZATION_HEADER "Authorization"
  8. #define AUTHORIZATION_HEADER_PREFIX "Bearer "
  9. #define AUTHORIZATION_HEADER_PREFIX_LEN 7
  10. #define MAX_JWT_SIZE 128
  11. class User {
  12. private:
  13. String _username;
  14. String _password;
  15. bool _admin;
  16. public:
  17. User(String username, String password, bool admin) : _username(username), _password(password), _admin(admin) {
  18. }
  19. String getUsername() {
  20. return _username;
  21. }
  22. String getPassword() {
  23. return _password;
  24. }
  25. bool isAdmin() {
  26. return _admin;
  27. }
  28. };
  29. class Authentication {
  30. private:
  31. User* _user;
  32. boolean _authenticated;
  33. public:
  34. Authentication(User& user) : _user(new User(user)), _authenticated(true) {
  35. }
  36. Authentication() : _user(nullptr), _authenticated(false) {
  37. }
  38. ~Authentication() {
  39. delete (_user);
  40. }
  41. User* getUser() {
  42. return _user;
  43. }
  44. bool isAuthenticated() {
  45. return _authenticated;
  46. }
  47. };
  48. typedef std::function<boolean(Authentication& authentication)> AuthenticationPredicate;
  49. class AuthenticationPredicates {
  50. public:
  51. static bool NONE_REQUIRED(Authentication& authentication) {
  52. return true;
  53. };
  54. static bool IS_AUTHENTICATED(Authentication& authentication) {
  55. return authentication.isAuthenticated();
  56. };
  57. static bool IS_ADMIN(Authentication& authentication) {
  58. return authentication.isAuthenticated() && authentication.getUser()->isAdmin();
  59. };
  60. };
  61. class SecurityManager {
  62. public:
  63. /*
  64. * Authenticate, returning the user if found
  65. */
  66. Authentication authenticate(String username, String password);
  67. /*
  68. * Check the request header for the Authorization token
  69. */
  70. Authentication authenticateRequest(AsyncWebServerRequest* request);
  71. /*
  72. * Generate a JWT for the user provided
  73. */
  74. String generateJWT(User* user);
  75. /**
  76. * Wrap the provided request to provide validation against an AuthenticationPredicate.
  77. */
  78. ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate);
  79. protected:
  80. ArduinoJsonJWT _jwtHandler = ArduinoJsonJWT(DEFAULT_JWT_SECRET);
  81. std::list<User> _users;
  82. private:
  83. /*
  84. * Lookup the user by JWT
  85. */
  86. Authentication authenticateJWT(String jwt);
  87. /*
  88. * Verify the payload is correct
  89. */
  90. boolean validatePayload(JsonObject& parsedPayload, User* user);
  91. };
  92. #endif // end SecurityManager_h