Redfish Session : Support ClientOriginIPAddress
This commit implements the ClientOriginIPAddress property on
the session resource. The IP address is persisted across the reboot
Tested by:
1. Create session
POST https://${bmc}/redfish/v1/SessionService/Sessions -d '{"UserName":<>, "Password":<>}'
2. Check the session gets updated with the ClientOriginIPAddress
GET https://${bmc}/redfish/v1/SessionService/Sessions/<id>
3. Redfish validator passed
4. Create session and reboot the BMC to ensure the IP address is persisted
5. Tested the basic auth populates the clientIp at req
Signed-off-by: Sunitha Harish <sunharis@in.ibm.com>
Change-Id: Iaa60d0657c991bde4bcf6c86819055c71c92e421
diff --git a/http/http_connection.hpp b/http/http_connection.hpp
index ec8e9d5..6610bee 100644
--- a/http/http_connection.hpp
+++ b/http/http_connection.hpp
@@ -241,7 +241,8 @@
session =
persistent_data::SessionStore::getInstance()
.generateUserSession(
- sslUser, persistent_data::PersistenceType::TIMEOUT);
+ sslUser, persistent_data::PersistenceType::TIMEOUT,
+ false, req->ipAddress.to_string());
if (auto sp = session.lock())
{
BMCWEB_LOG_DEBUG << this
@@ -278,6 +279,10 @@
{
startDeadline(0);
+
+ // Fetch the client IP address
+ readClientIp();
+
// TODO(ed) Abstract this to a more clever class with the idea of an
// asynchronous "start"
if constexpr (std::is_same_v<Adaptor,
@@ -319,7 +324,7 @@
BMCWEB_LOG_INFO << "Request: "
<< " " << this << " HTTP/" << req->version() / 10 << "."
<< req->version() % 10 << ' ' << req->methodString()
- << " " << req->target();
+ << " " << req->target() << " " << req->ipAddress;
needToCallAfterHandlers = false;
@@ -461,6 +466,26 @@
res.completeRequestHandler = nullptr;
}
+ void readClientIp()
+ {
+ boost::system::error_code ec;
+ BMCWEB_LOG_DEBUG << "Fetch the client IP address";
+ boost::asio::ip::tcp::endpoint endpoint =
+ boost::beast::get_lowest_layer(adaptor).remote_endpoint(ec);
+
+ if (ec)
+ {
+ // If remote endpoint fails keep going. "ClientOriginIPAddress"
+ // will be empty.
+ BMCWEB_LOG_ERROR << "Failed to get the client's IP Address. ec : "
+ << ec;
+ }
+ else
+ {
+ req->ipAddress = endpoint.address();
+ }
+ }
+
private:
void doReadHeaders()
{
diff --git a/http/http_request.hpp b/http/http_request.hpp
index e5c0c9e..8bcce06 100644
--- a/http/http_request.hpp
+++ b/http/http_request.hpp
@@ -4,6 +4,7 @@
#include "sessions.hpp"
#include <boost/asio/io_context.hpp>
+#include <boost/asio/ip/address.hpp>
#include <boost/beast/http/message.hpp>
#include <boost/beast/http/string_body.hpp>
#include <boost/beast/websocket.hpp>
@@ -24,6 +25,7 @@
const std::string& body;
boost::asio::io_context* ioService{};
+ boost::asio::ip::address ipAddress{};
std::shared_ptr<persistent_data::UserSession> session;