diff options
author | Zbigniew Kurzynski <zbigniew.kurzynski@intel.com> | 2019-11-05 14:57:37 +0300 |
---|---|---|
committer | Zbigniew Kurzynski <zbigniew.kurzynski@intel.com> | 2019-11-07 09:39:29 +0300 |
commit | 78158631aeab5b77ea9a5f566508285cb839fadf (patch) | |
tree | 71d49ec71414858c532c121df98c9b6b629e7987 /redfish-core | |
parent | 1f8c7b5d6a679a38b82261060310b876079d0f8b (diff) | |
download | bmcweb-78158631aeab5b77ea9a5f566508285cb839fadf.tar.xz |
Auth methods configuration
Added Oem extension for AccountService allowing user to configure
which authentication methods should be enabled. User is now able
to turn on and off authentication methods like BasicAuth, XToken, etc.
User is not allowed to turn off all of the methods at once - at least
one method has to be active to prevent lock-out. This configuration
is persistent, will be saved on file-system and will be loaded on
bmcweb's restart.
Tested:
No regression found in manual testing. By default everything works as before,
and disabling auth method prevents user to authenticate by it. Tested that
user is not allowed to disable all the methods - either in one PATCH or by
disabling them one at a time.
ServiceValidator run with success.
This change is a fix for this request:
https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/23590/18
which was revert here:
https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/26869
Signed-off-by: Zbigniew Kurzynski <zbigniew.kurzynski@intel.com>
Change-Id: I66b5ad423746f1992070a14f2983a07b1320190e
Diffstat (limited to 'redfish-core')
-rw-r--r-- | redfish-core/lib/account_service.hpp | 109 |
1 files changed, 101 insertions, 8 deletions
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp index 59e2d1cd67..bc8ce771d6 100644 --- a/redfish-core/lib/account_service.hpp +++ b/redfish-core/lib/account_service.hpp @@ -553,7 +553,8 @@ inline void getLDAPConfigData(const std::string& ldapType, class AccountService : public Node { public: - AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/") + AccountService(CrowApp& app) : + Node(app, "/redfish/v1/AccountService/"), app(app) { entityPrivileges = { {boost::beast::http::verb::get, @@ -887,6 +888,65 @@ class AccountService : public Node ldapEnableInterface, "Enabled", std::variant<bool>(serviceEnabled)); } + void handleAuthMethodsPatch(nlohmann::json& input, + const std::shared_ptr<AsyncResp>& asyncResp) + { + std::optional<bool> basicAuth; + std::optional<bool> cookie; + std::optional<bool> sessionToken; + std::optional<bool> xToken; + + if (!json_util::readJson(input, asyncResp->res, "BasicAuth", basicAuth, + "Cookie", cookie, "SessionToken", sessionToken, + "XToken", xToken)) + { + BMCWEB_LOG_ERROR << "Cannot read values from AuthMethod tag"; + return; + } + + // Make a copy of methods configuration + crow::persistent_data::AuthConfigMethods authMethodsConfig = + crow::persistent_data::SessionStore::getInstance() + .getAuthMethodsConfig(); + + if (basicAuth) + { + authMethodsConfig.basic = *basicAuth; + } + + if (cookie) + { + authMethodsConfig.cookie = *cookie; + } + + if (sessionToken) + { + authMethodsConfig.sessionToken = *sessionToken; + } + + if (xToken) + { + authMethodsConfig.xtoken = *xToken; + } + + if (!authMethodsConfig.basic && !authMethodsConfig.cookie && + !authMethodsConfig.sessionToken && !authMethodsConfig.xtoken) + { + // Do not allow user to disable everything + messages::actionNotSupported(asyncResp->res, + "of disabling all available methods"); + return; + } + + crow::persistent_data::SessionStore::getInstance() + .updateAuthMethodsConfig(authMethodsConfig); + // Save configuration immediately + app.template getMiddleware<crow::persistent_data::Middleware>() + .writeData(); + + messages::success(asyncResp->res); + } + /** * @brief Get the required values from the given JSON, validates the * value and create the LDAP config object. @@ -1063,6 +1123,10 @@ class AccountService : public Node void doGet(crow::Response& res, const crow::Request& req, const std::vector<std::string>& params) override { + const crow::persistent_data::AuthConfigMethods& authMethodsConfig = + crow::persistent_data::SessionStore::getInstance() + .getAuthMethodsConfig(); + auto asyncResp = std::make_shared<AsyncResp>(res); res.jsonValue = { {"@odata.context", "/redfish/v1/" @@ -1078,6 +1142,16 @@ class AccountService : public Node {"Accounts", {{"@odata.id", "/redfish/v1/AccountService/Accounts"}}}, {"Roles", {{"@odata.id", "/redfish/v1/AccountService/Roles"}}}, + {"Oem", + {{"OpenBMC", + {{"@odata.type", "#OemAccountService.v1_0_0.AccountService"}, + {"AuthMethods", + { + {"BasicAuth", authMethodsConfig.basic}, + {"SessionToken", authMethodsConfig.sessionToken}, + {"XToken", authMethodsConfig.xtoken}, + {"Cookie", authMethodsConfig.cookie}, + }}}}}}, {"LDAP", {{"Certificates", {{"@odata.id", @@ -1155,13 +1229,14 @@ class AccountService : public Node std::optional<uint16_t> maxPasswordLength; std::optional<nlohmann::json> ldapObject; std::optional<nlohmann::json> activeDirectoryObject; - - if (!json_util::readJson(req, res, "AccountLockoutDuration", - unlockTimeout, "AccountLockoutThreshold", - lockoutThreshold, "MaxPasswordLength", - maxPasswordLength, "MinPasswordLength", - minPasswordLength, "LDAP", ldapObject, - "ActiveDirectory", activeDirectoryObject)) + std::optional<nlohmann::json> oemObject; + + if (!json_util::readJson( + req, res, "AccountLockoutDuration", unlockTimeout, + "AccountLockoutThreshold", lockoutThreshold, + "MaxPasswordLength", maxPasswordLength, "MinPasswordLength", + minPasswordLength, "LDAP", ldapObject, "ActiveDirectory", + activeDirectoryObject, "Oem", oemObject)) { return; } @@ -1181,6 +1256,22 @@ class AccountService : public Node handleLDAPPatch(*ldapObject, asyncResp, req, params, "LDAP"); } + if (std::optional<nlohmann::json> oemOpenBMCObject; + oemObject && + json_util::readJson(*oemObject, res, "OpenBMC", oemOpenBMCObject)) + { + if (std::optional<nlohmann::json> authMethodsObject; + oemOpenBMCObject && + json_util::readJson(*oemOpenBMCObject, res, "AuthMethods", + authMethodsObject)) + { + if (authMethodsObject) + { + handleAuthMethodsPatch(*authMethodsObject, asyncResp); + } + } + } + if (activeDirectoryObject) { handleLDAPPatch(*activeDirectoryObject, asyncResp, req, params, @@ -1221,6 +1312,8 @@ class AccountService : public Node std::variant<uint16_t>(*lockoutThreshold)); } } + + CrowApp& app; }; class AccountsCollection : public Node |