| 300 | |
| 301 | |
| 302 | bool HTTPHandler::authenticateUser( |
| 303 | ContextMutablePtr context, |
| 304 | HTTPServerRequest & request, |
| 305 | HTMLForm & params, |
| 306 | HTTPServerResponse & response) |
| 307 | { |
| 308 | using namespace Poco::Net; |
| 309 | |
| 310 | /// The user and password can be passed by headers (similar to X-Auth-*), |
| 311 | /// which is used by load balancers to pass authentication information. |
| 312 | std::string user = request.get("X-ClickHouse-User", ""); |
| 313 | std::string password = request.get("X-ClickHouse-Key", ""); |
| 314 | std::string quota_key = request.get("X-ClickHouse-Quota", ""); |
| 315 | |
| 316 | std::string spnego_challenge; |
| 317 | |
| 318 | if (user.empty() && password.empty() && quota_key.empty()) |
| 319 | { |
| 320 | /// User name and password can be passed using query parameters |
| 321 | /// or using HTTP Basic auth (both methods are insecure). |
| 322 | if (request.hasCredentials()) |
| 323 | { |
| 324 | /// It is prohibited to mix different authorization schemes. |
| 325 | if (params.has("user") || params.has("password")) |
| 326 | throw Exception("Invalid authentication: it is not allowed to use Authorization HTTP header and authentication via parameters simultaneously", ErrorCodes::AUTHENTICATION_FAILED); |
| 327 | |
| 328 | std::string scheme; |
| 329 | std::string auth_info; |
| 330 | request.getCredentials(scheme, auth_info); |
| 331 | |
| 332 | if (Poco::icompare(scheme, "Basic") == 0) |
| 333 | { |
| 334 | HTTPBasicCredentials credentials(auth_info); |
| 335 | user = credentials.getUsername(); |
| 336 | password = credentials.getPassword(); |
| 337 | } |
| 338 | else if (Poco::icompare(scheme, "Negotiate") == 0) |
| 339 | { |
| 340 | spnego_challenge = auth_info; |
| 341 | |
| 342 | if (spnego_challenge.empty()) |
| 343 | throw Exception("Invalid authentication: SPNEGO challenge is empty", ErrorCodes::AUTHENTICATION_FAILED); |
| 344 | } |
| 345 | else |
| 346 | { |
| 347 | throw Exception("Invalid authentication: '" + scheme + "' HTTP Authorization scheme is not supported", ErrorCodes::AUTHENTICATION_FAILED); |
| 348 | } |
| 349 | } |
| 350 | else |
| 351 | { |
| 352 | user = params.get("user", "default"); |
| 353 | password = params.get("password", ""); |
| 354 | } |
| 355 | |
| 356 | quota_key = params.get("quota_key", ""); |
| 357 | } |
| 358 | else |
| 359 | { |
nothing calls this directly
no test coverage detected