60 std::string_view& auth_header_value, std::string& error_reason)
62 auto next_space = auth_header_value.find(
" ");
63 if (next_space == std::string::npos)
65 error_reason =
"Authorization header only contains one field";
68 auto auth_scheme = auth_header_value.substr(0, next_space);
69 if (auth_scheme != ccf::http::auth::BEARER_AUTH_SCHEME)
71 error_reason = fmt::format(
72 "Authorization header does not have {} scheme",
73 ccf::http::auth::BEARER_AUTH_SCHEME);
76 auth_header_value = auth_header_value.substr(next_space + 1);
81 std::string_view& token, std::string& error_reason)
83 constexpr char separator =
'.';
84 size_t first_dot = token.find(separator);
85 size_t second_dot = std::string::npos;
86 if (first_dot != std::string::npos)
88 second_dot = token.find(separator, first_dot + 1);
90 size_t extra_dot = std::string::npos;
91 if (second_dot != std::string::npos)
93 extra_dot = token.find(separator, second_dot + 1);
96 first_dot == std::string::npos || second_dot == std::string::npos ||
97 extra_dot != std::string::npos)
99 error_reason =
"Malformed JWT: must contain exactly 3 parts";
102 size_t header_size = first_dot;
103 size_t payload_size = second_dot - first_dot - 1;
104 std::string_view header_b64url = token.substr(0, header_size);
105 std::string_view payload_b64url =
106 token.substr(first_dot + 1, payload_size);
107 std::string_view signature_b64url = token.substr(second_dot + 1);
111 auto signed_content = token.substr(0, second_dot);
112 nlohmann::json header;
113 nlohmann::json payload;
116 header = nlohmann::json::parse(header_raw);
117 payload = nlohmann::json::parse(payload_raw);
119 catch (
const nlohmann::json::parse_error& e)
122 fmt::format(
"JWT header or payload is not valid JSON: {}", e.what());
125 if (!header.is_object() || !payload.is_object())
127 error_reason =
"JWT header or payload is not an object";
138 fmt::format(
"JWT header does not follow schema: {}", e.describe());
148 error_reason = fmt::format(
149 "JWT payload is missing required field: {}", e.describe());
165 const auto auth_it = headers.find(ccf::http::headers::AUTHORIZATION);
166 if (auth_it == headers.end())
169 fmt::format(
"Missing {} header", ccf::http::headers::AUTHORIZATION);
172 std::string_view token = auth_it->second;
173 if (!parse_auth_scheme(token, error_reason))
177 auto parsed = parse_token(token, error_reason);