diff options
Diffstat (limited to 'include/authorization.hpp')
-rw-r--r-- | include/authorization.hpp | 130 |
1 files changed, 67 insertions, 63 deletions
diff --git a/include/authorization.hpp b/include/authorization.hpp index b1d1097068..ecbdca04c0 100644 --- a/include/authorization.hpp +++ b/include/authorization.hpp @@ -93,36 +93,37 @@ static std::shared_ptr<persistent_data::UserSession> BMCWEB_LOG_DEBUG << "[AuthMiddleware] Token authentication"; std::string_view token = authHeader.substr(strlen("Token ")); - auto session = + auto sessionOut = persistent_data::SessionStore::getInstance().loginSessionByToken(token); - return session; + return sessionOut; } #endif #ifdef BMCWEB_ENABLE_XTOKEN_AUTHENTICATION static std::shared_ptr<persistent_data::UserSession> - performXtokenAuth(const crow::Request& req) + performXtokenAuth(const boost::beast::http::header<true>& reqHeader) { BMCWEB_LOG_DEBUG << "[AuthMiddleware] X-Auth-Token authentication"; - std::string_view token = req.getHeaderValue("X-Auth-Token"); + std::string_view token = reqHeader["X-Auth-Token"]; if (token.empty()) { return nullptr; } - auto session = + auto sessionOut = persistent_data::SessionStore::getInstance().loginSessionByToken(token); - return session; + return sessionOut; } #endif #ifdef BMCWEB_ENABLE_COOKIE_AUTHENTICATION static std::shared_ptr<persistent_data::UserSession> - performCookieAuth(const crow::Request& req) + performCookieAuth(boost::beast::http::verb method, + const boost::beast::http::header<true>& reqHeader) { BMCWEB_LOG_DEBUG << "[AuthMiddleware] Cookie authentication"; - std::string_view cookieValue = req.getHeaderValue("Cookie"); + std::string_view cookieValue = reqHeader["Cookie"]; if (cookieValue.empty()) { return nullptr; @@ -142,20 +143,20 @@ static std::shared_ptr<persistent_data::UserSession> std::string_view authKey = cookieValue.substr(startIndex, endIndex - startIndex); - std::shared_ptr<persistent_data::UserSession> session = + std::shared_ptr<persistent_data::UserSession> sessionOut = persistent_data::SessionStore::getInstance().loginSessionByToken( authKey); - if (session == nullptr) + if (sessionOut == nullptr) { return nullptr; } #ifndef BMCWEB_INSECURE_DISABLE_CSRF_PREVENTION // RFC7231 defines methods that need csrf protection - if (req.method() != boost::beast::http::verb::get) + if (method != boost::beast::http::verb::get) { - std::string_view csrf = req.getHeaderValue("X-XSRF-TOKEN"); + std::string_view csrf = reqHeader["X-XSRF-TOKEN"]; // Make sure both tokens are filled - if (csrf.empty() || session->csrfToken.empty()) + if (csrf.empty() || sessionOut->csrfToken.empty()) { return nullptr; } @@ -165,31 +166,33 @@ static std::shared_ptr<persistent_data::UserSession> return nullptr; } // Reject if csrf token not available - if (!crow::utility::constantTimeStringCompare(csrf, session->csrfToken)) + if (!crow::utility::constantTimeStringCompare(csrf, + sessionOut->csrfToken)) { return nullptr; } } #endif - return session; + return sessionOut; } #endif #ifdef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION static std::shared_ptr<persistent_data::UserSession> - performTLSAuth(const crow::Request& req, Response& res, + performTLSAuth(Response& res, + const boost::beast::http::header<true>& reqHeader, const std::weak_ptr<persistent_data::UserSession>& session) { if (auto sp = session.lock()) { // set cookie only if this is req from the browser. - if (req.getHeaderValue("User-Agent").empty()) + if (reqHeader["User-Agent"].empty()) { BMCWEB_LOG_DEBUG << " TLS session: " << sp->uniqueId << " will be used for this request."; return sp; } - std::string_view cookieValue = req.getHeaderValue("Cookie"); + std::string_view cookieValue = reqHeader["Cookie"]; if (cookieValue.empty() || cookieValue.find("SESSION=") == std::string::npos) { @@ -211,18 +214,17 @@ static std::shared_ptr<persistent_data::UserSession> #endif // checks if request can be forwarded without authentication -static bool isOnWhitelist(const crow::Request& req) +static bool isOnWhitelist(std::string_view url, boost::beast::http::verb method) { - // it's allowed to GET root node without authentication - if (boost::beast::http::verb::get == req.method()) + if (boost::beast::http::verb::get == method) { - if (req.url == "/redfish/v1" || req.url == "/redfish/v1/" || - req.url == "/redfish" || req.url == "/redfish/" || - req.url == "/redfish/v1/odata" || req.url == "/redfish/v1/odata/") + if (url == "/redfish/v1" || url == "/redfish/v1/" || + url == "/redfish" || url == "/redfish/" || + url == "/redfish/v1/odata" || url == "/redfish/v1/odata/") { return true; } - if (crow::webroutes::routes.find(std::string(req.url)) != + if (crow::webroutes::routes.find(std::string(url)) != crow::webroutes::routes.end()) { return true; @@ -231,11 +233,11 @@ static bool isOnWhitelist(const crow::Request& req) // it's allowed to POST on session collection & login without // authentication - if (boost::beast::http::verb::post == req.method()) + if (boost::beast::http::verb::post == method) { - if ((req.url == "/redfish/v1/SessionService/Sessions") || - (req.url == "/redfish/v1/SessionService/Sessions/") || - (req.url == "/login")) + if ((url == "/redfish/v1/SessionService/Sessions") || + (url == "/redfish/v1/SessionService/Sessions/") || + (url == "/login")) { return true; } @@ -244,66 +246,68 @@ static bool isOnWhitelist(const crow::Request& req) return false; } -static void authenticate( - crow::Request& req, Response& res, - [[maybe_unused]] const std::weak_ptr<persistent_data::UserSession>& session) +static std::shared_ptr<persistent_data::UserSession> authenticate( + std::string_view url, boost::asio::ip::address& ipAddress, Response& res, + boost::beast::http::verb method, + const boost::beast::http::header<true>& reqHeader, + [[maybe_unused]] const std::shared_ptr<persistent_data::UserSession>& + session) { - if (isOnWhitelist(req)) + if (isOnWhitelist(url, method)) { - return; + return nullptr; } - const persistent_data::AuthConfigMethods& authMethodsConfig = persistent_data::SessionStore::getInstance().getAuthMethodsConfig(); + std::shared_ptr<persistent_data::UserSession> sessionOut = nullptr; #ifdef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION - if (req.session == nullptr && authMethodsConfig.tls) + if (authMethodsConfig.tls) { - req.session = performTLSAuth(req, res, session); + sessionOut = performTLSAuth(res, reqHeader, session); } #endif #ifdef BMCWEB_ENABLE_XTOKEN_AUTHENTICATION - if (req.session == nullptr && authMethodsConfig.xtoken) + if (sessionOut == nullptr && authMethodsConfig.xtoken) { - req.session = performXtokenAuth(req); + sessionOut = performXtokenAuth(reqHeader); } #endif #ifdef BMCWEB_ENABLE_COOKIE_AUTHENTICATION - if (req.session == nullptr && authMethodsConfig.cookie) + if (sessionOut == nullptr && authMethodsConfig.cookie) { - req.session = performCookieAuth(req); + sessionOut = performCookieAuth(method, reqHeader); } #endif - if (req.session == nullptr) + std::string_view authHeader = reqHeader["Authorization"]; + + if (!authHeader.empty()) { - std::string_view authHeader = req.getHeaderValue("Authorization"); - if (!authHeader.empty()) + // Reject any kind of auth other than basic or token + if (boost::starts_with(authHeader, "Token ") && + authMethodsConfig.sessionToken) { - // Reject any kind of auth other than basic or token - if (boost::starts_with(authHeader, "Token ") && - authMethodsConfig.sessionToken) - { #ifdef BMCWEB_ENABLE_SESSION_AUTHENTICATION - req.session = performTokenAuth(authHeader); + sessionOut = performTokenAuth(authHeader); #endif - } - else if (boost::starts_with(authHeader, "Basic ") && - authMethodsConfig.basic) - { + } + else if (boost::starts_with(authHeader, "Basic ") && + authMethodsConfig.basic) + { #ifdef BMCWEB_ENABLE_BASIC_AUTHENTICATION - req.session = performBasicAuth(req.ipAddress, authHeader); + sessionOut = performBasicAuth(ipAddress, authHeader); #endif - } + } + if (sessionOut != nullptr) + { + return sessionOut; } } - - if (req.session == nullptr) - { - BMCWEB_LOG_WARNING << "[AuthMiddleware] authorization failed"; - forward_unauthorized::sendUnauthorized(req, res); - res.end(); - return; - } + BMCWEB_LOG_WARNING << "[AuthMiddleware] authorization failed"; + forward_unauthorized::sendUnauthorized(url, reqHeader["User-Agent"], + reqHeader["accept"], res); + res.end(); + return nullptr; } } // namespace authorization |