9#include <unordered_map>
19namespace mcp::server {
23inline bool ascii_iequals(std::string_view lhs, std::string_view rhs) {
24 if (lhs.size() != rhs.size()) {
27 for (std::size_t index = 0; index < lhs.size(); ++index) {
28 const auto left =
static_cast<unsigned char>(lhs[index]);
29 const auto right =
static_cast<unsigned char>(rhs[index]);
30 if (std::tolower(left) != std::tolower(right)) {
38 std::string_view rhs) {
39 const auto max_size = lhs.size() > rhs.size() ? lhs.size() : rhs.size();
40 unsigned char diff =
static_cast<unsigned char>(lhs.size() ^ rhs.size());
41 for (std::size_t index = 0; index < max_size; ++index) {
43 index < lhs.size() ?
static_cast<unsigned char>(lhs[index]) : 0;
45 index < rhs.size() ?
static_cast<unsigned char>(rhs[index]) : 0;
46 diff =
static_cast<unsigned char>(diff | (left ^ right));
51inline std::string_view trim_ascii(std::string_view value) {
52 while (!value.empty() &&
53 std::isspace(
static_cast<unsigned char>(value.front())) != 0) {
54 value.remove_prefix(1);
56 while (!value.empty() &&
57 std::isspace(
static_cast<unsigned char>(value.back())) != 0) {
58 value.remove_suffix(1);
63inline std::string_view bearer_token_from_authorization(
64 std::string_view authorization) {
65 authorization = trim_ascii(authorization);
66 constexpr std::string_view kBearer =
"Bearer";
67 if (authorization.size() <= kBearer.size() ||
68 !ascii_iequals(authorization.substr(0, kBearer.size()), kBearer) ||
69 std::isspace(
static_cast<unsigned char>(authorization[kBearer.size()])) ==
73 authorization.remove_prefix(kBearer.size());
74 authorization = trim_ascii(authorization);
81inline constexpr std::string_view AuthErrorCategory =
"auth";
93 std::unordered_map<std::string, std::string>
headers;
108 std::unordered_map<std::string, std::string>
claims;
133 std::string detail = {}) {
135 static_cast<int>(protocol::ErrorCode::PermissionDenied),
138 std::string(AuthErrorCategory),
158 : entries_(std::move(entries)) {}
160 void add_token(std::string token,
AuthIdentity identity) {
161 entries_.push_back(Entry{std::move(token), std::move(identity)});
165 const auto token = bearer_token(request);
167 return mcp::core::unexpected(
171 for (
const auto& entry : entries_) {
172 if (detail::constant_time_string_equal(token, entry.token)) {
173 return entry.identity;
176 return mcp::core::unexpected(
181 static std::string_view bearer_token(
const AuthRequest& request) {
182 for (
const auto& header : request.headers) {
183 if (detail::ascii_iequals(header.first,
"Authorization")) {
184 return detail::bearer_token_from_authorization(header.second);
190 std::vector<Entry> entries_;
Abstract authentication provider used by server integrations.
Definition auth.hpp:117
virtual core::Result< AuthIdentity > authenticate(const AuthRequest &request)=0
Authenticate a transport request.
Static bearer-token AuthProvider for small embedded deployments and tests.
Definition auth.hpp:149
core::Result< AuthIdentity > authenticate(const AuthRequest &request) override
Authenticate a transport request.
Definition auth.hpp:164
bool constant_time_string_equal(std::string_view lhs, std::string_view rhs) noexcept
Compare two strings without data-dependent early exit.
Definition constant_time.hpp:17
Shared JSON, JSON-RPC, error, cancellation, and progress model types.
Shared result and error primitives used by the public cxxmcp SDK.
tl::expected< T, Error > Result
Alias for the SDK result type.
Definition result.hpp:64
constexpr std::string_view DefaultAuthChallenge
Default HTTP challenge used when a transport has no custom policy.
Definition auth.hpp:84
core::Error make_auth_error(std::string message, std::string detail={})
Build a structured authentication failure for transports.
Definition auth.hpp:132
Structured error returned by fallible SDK operations.
Definition result.hpp:35
Authenticated principal and associated claims.
Definition auth.hpp:103
std::string subject
Stable principal identifier, such as a user id, service account, or token subject.
Definition auth.hpp:106
std::unordered_map< std::string, std::string > claims
Provider-specific claims copied by value into the identity.
Definition auth.hpp:108
Transport-neutral authentication input.
Definition auth.hpp:91
std::string remote_address
Best-effort remote address for audit and policy decisions.
Definition auth.hpp:95
std::unordered_map< std::string, std::string > headers
Request headers or metadata supplied by the transport.
Definition auth.hpp:93
std::optional< std::string > http_url
Absolute HTTP request URL when supplied by an HTTP-based transport.
Definition auth.hpp:99
std::optional< std::string > http_method
HTTP request method when supplied by an HTTP-based transport.
Definition auth.hpp:97