56 std::string_view& auth_header_value, std::string& error_reason)
58 auto next_space = auth_header_value.find(
" ");
59 if (next_space == std::string::npos)
61 error_reason =
"Authorization header only contains one field";
64 auto auth_scheme = auth_header_value.substr(0, next_space);
65 if (auth_scheme != ccf::http::auth::BEARER_AUTH_SCHEME)
67 error_reason = fmt::format(
68 "Authorization header does not have {} scheme",
69 ccf::http::auth::BEARER_AUTH_SCHEME);
72 auth_header_value = auth_header_value.substr(next_space + 1);
77 std::string_view& token, std::string& error_reason)
79 constexpr char separator =
'.';
80 size_t first_dot = token.find(separator);
81 size_t second_dot = std::string::npos;
82 if (first_dot != std::string::npos)
84 second_dot = token.find(separator, first_dot + 1);
86 size_t extra_dot = std::string::npos;
87 if (second_dot != std::string::npos)
89 extra_dot = token.find(separator, second_dot + 1);
92 first_dot == std::string::npos || second_dot == std::string::npos ||
93 extra_dot != std::string::npos)
95 error_reason =
"Malformed JWT: must contain exactly 3 parts";
98 size_t header_size = first_dot;
99 size_t payload_size = second_dot - first_dot - 1;
100 std::string_view header_b64url = token.substr(0, header_size);
101 std::string_view payload_b64url =
102 token.substr(first_dot + 1, payload_size);
103 std::string_view signature_b64url = token.substr(second_dot + 1);
107 auto signed_content = token.substr(0, second_dot);
108 nlohmann::json header;
109 nlohmann::json payload;
112 header = nlohmann::json::parse(header_raw);
113 payload = nlohmann::json::parse(payload_raw);
115 catch (
const nlohmann::json::parse_error& e)
118 fmt::format(
"JWT header or payload is not valid JSON: {}", e.what());
121 if (!header.is_object() || !payload.is_object())
123 error_reason =
"JWT header or payload is not an object";
134 fmt::format(
"JWT header does not follow schema: {}", e.describe());
144 error_reason = fmt::format(
145 "JWT payload is missing required field: {}", e.describe());
161 const auto auth_it = headers.find(ccf::http::headers::AUTHORIZATION);
162 if (auth_it == headers.end())
165 fmt::format(
"Missing {} header", ccf::http::headers::AUTHORIZATION);
168 std::string_view token = auth_it->second;
169 if (!parse_auth_scheme(token, error_reason))
173 auto parsed = parse_token(token, error_reason);