Implementation:ClickHouse ClickHouse Poco HTTPAuthenticationParams
| Source File | base/poco/Net/src/HTTPAuthenticationParams.cpp |
|---|---|
| Lines of Code | 316 |
| Principle | Principle:ClickHouse_ClickHouse_HTTP_Authentication |
| Domain | Networking, Security |
| Language | C++ |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
Parser and container for HTTP authentication parameters used in `WWW-Authenticate` and `Proxy-Authenticate` headers, supporting both Basic and Digest authentication schemes.
Purpose
Provides structured parsing and storage of HTTP authentication challenge parameters, enabling credential validation and response generation for HTTP authentication.
Key Classes
- HTTPAuthenticationParams: Extends `NameValueCollection` to store authentication parameters
Core Functionality
Construction
Multiple initialization options:
// Empty constructor
HTTPAuthenticationParams();
// From authentication info string
HTTPAuthenticationParams(const std::string& authInfo);
// From HTTP request (Authorization header)
HTTPAuthenticationParams(const HTTPRequest& request);
// From HTTP response (WWW-Authenticate/Proxy-Authenticate)
HTTPAuthenticationParams(const HTTPResponse& response, const std::string& header);
Parameter Extraction
Methods to populate from various sources:
// Parse authentication info string
void fromAuthInfo(const std::string& authInfo);
// Extract from request Authorization header
void fromRequest(const HTTPRequest& request);
// Extract from response authentication header
void fromResponse(const HTTPResponse& response, const std::string& header);
Realm Access
Convenient access to the realm parameter:
const std::string& getRealm() const;
void setRealm(const std::string& realm);
String Conversion
Convert parameters back to header format:
std::string toString() const;
Formats parameters with proper quoting for HTTP headers.
Implementation Details
Parameter Parsing
State machine parser for authentication parameters:
void parse(std::string::const_iterator first, std::string::const_iterator last) {
enum State {
STATE_SPACE, // Whitespace
STATE_TOKEN, // Reading parameter name
STATE_EQUALS, // After '='
STATE_VALUE, // Unquoted value
STATE_VALUE_QUOTED, // Quoted value
STATE_VALUE_ESCAPE, // Escape sequence in quoted value
STATE_COMMA // After value, expecting comma
};
// Parse key="value", key=value pairs
}
Handles:
- Quoted and unquoted values
- Escape sequences in quoted values
- Comma-separated parameters
- Whitespace tolerance
Header Extraction
Extracts from HTTP response headers:
void fromResponse(const HTTPResponse& response, const std::string& header) {
// Find header (WWW-Authenticate or Proxy-Authenticate)
// Look for "Basic " or "Digest " prefix
// Parse parameters following scheme
// Throw if no authentication header found
}
Supports multiple authentication challenges in one response.
Parameter Formatting
Converts to string with proper quoting:
std::string toString() const {
// Format: param1="value1", param2="value2", ...
// Quote certain parameters: realm, nonce, opaque, qop, etc.
// Leave others unquoted: nc, algorithm
}
Parameters requiring quotes:
- `realm`, `domain`, `nonce`, `opaque`
- `qop`, `uri`, `response`
- `username`, `cnonce`
Constants
static const std::string REALM; // "realm"
static const std::string WWW_AUTHENTICATE; // "WWW-Authenticate"
static const std::string PROXY_AUTHENTICATE; // "Proxy-Authenticate"
Usage Examples
Parsing Server Challenge
// From HTTP response
HTTPResponse response;
// ... receive response with 401 status ...
HTTPAuthenticationParams params(response, HTTPAuthenticationParams::WWW_AUTHENTICATE);
std::string realm = params.getRealm();
std::string nonce = params.get("nonce");
std::string qop = params.get("qop", "");
Parsing Client Credentials
// From HTTP request
HTTPRequest request;
// ... receive request with Authorization header ...
try {
HTTPAuthenticationParams params(request);
std::string username = params.get("username");
std::string response = params.get("response");
// Verify credentials
} catch (NotAuthenticatedException&) {
// No valid authentication
}
Creating Authentication Parameters
HTTPAuthenticationParams params;
params.setRealm("Protected Area");
params.set("nonce", generateNonce());
params.set("algorithm", "MD5");
params.set("qop", "auth");
std::string headerValue = "Digest " + params.toString();
response.set("WWW-Authenticate", headerValue);
Parsing Authentication String
std::string authInfo = "realm=\"Protected\", nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\"";
HTTPAuthenticationParams params(authInfo);
Security Considerations
Input Validation
- Validates parameter syntax
- Checks for proper quoting
- Detects malformed headers
- Throws `SyntaxException` for invalid input
Scheme Validation
- Verifies "Basic" or "Digest" scheme
- Case-insensitive comparison
- Throws `NotAuthenticatedException` for unsupported schemes
Parameter Extraction
- Safely extracts quoted and unquoted values
- Handles escape sequences properly
- Prevents injection attacks through proper parsing
Error Handling
Exception types:
- SyntaxException: Malformed authentication parameters
- NotAuthenticatedException: Missing or invalid authentication headers
- InvalidArgumentException: Invalid scheme or parameters
Dependencies
- `Poco::Net::HTTPRequest`: HTTP request representation
- `Poco::Net::HTTPResponse`: HTTP response representation
- `Poco::Net::NameValueCollection`: Base class for parameter storage
- `Poco::String`: String comparison utilities
- `Poco::Ascii`: Character classification
Testing Considerations
- Test with various authentication schemes
- Verify quoted value parsing
- Test escape sequence handling
- Check comma-separated parameter lists
- Test with malformed inputs
- Verify case-insensitive scheme matching
- Test multiple authentication challenges