PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
jwt_validator.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
19#pragma once
20
22
23#include <cstdint>
24#include <optional>
25#include <string>
26#include <string_view>
27#include <vector>
28
30
31// =============================================================================
32// JWT Token Structures
33// =============================================================================
34
38struct jwt_header {
39 std::string alg;
40 std::string typ;
41 std::string kid;
42};
43
47struct jwt_claims {
48 std::string iss;
49 std::string sub;
50 std::string aud;
51 std::int64_t exp = 0;
52 std::int64_t iat = 0;
53 std::int64_t nbf = 0;
54 std::string jti;
55 std::vector<std::string> scopes;
56};
57
67
68// =============================================================================
69// JWT Error Types
70// =============================================================================
71
89
95[[nodiscard]] std::string_view jwt_error_message(jwt_error error) noexcept;
96
97// =============================================================================
98// JWT Validator
99// =============================================================================
100
125public:
130 explicit jwt_validator(const oauth2_config& config);
131
141 [[nodiscard]] std::pair<jwt_token, jwt_error> decode(
142 std::string_view token_string) const;
143
152 [[nodiscard]] jwt_error validate_claims(
153 const jwt_claims& claims) const;
154
161 [[nodiscard]] bool verify_rs256(
162 const jwt_token& token,
163 std::string_view public_key_pem) const;
164
171 [[nodiscard]] bool verify_es256(
172 const jwt_token& token,
173 std::string_view public_key_pem) const;
174
181 [[nodiscard]] static bool has_scope(
182 const jwt_claims& claims,
183 std::string_view scope) noexcept;
184
191 [[nodiscard]] static bool has_any_scope(
192 const jwt_claims& claims,
193 const std::vector<std::string>& scopes) noexcept;
194
198 [[nodiscard]] const oauth2_config& config() const noexcept;
199
200private:
202};
203
204// =============================================================================
205// Base64url Utilities
206// =============================================================================
207
213[[nodiscard]] std::optional<std::string> base64url_decode(
214 std::string_view input);
215
216} // namespace kcenon::pacs::web::auth
jwt_validator(const oauth2_config &config)
Construct validator with OAuth 2.0 configuration.
bool verify_es256(const jwt_token &token, std::string_view public_key_pem) const
Verify ES256 (ECDSA-SHA256) signature.
static bool has_any_scope(const jwt_claims &claims, const std::vector< std::string > &scopes) noexcept
Check if token has any of the specified scopes.
jwt_error validate_claims(const jwt_claims &claims) const
Validate JWT claims against configuration.
static bool has_scope(const jwt_claims &claims, std::string_view scope) noexcept
Check if token has a specific scope.
const oauth2_config & config() const noexcept
Get the OAuth 2.0 configuration.
bool verify_rs256(const jwt_token &token, std::string_view public_key_pem) const
Verify RS256 (RSA-SHA256) signature.
std::pair< jwt_token, jwt_error > decode(std::string_view token_string) const
Decode a JWT token string into its components.
jwt_error
JWT validation error codes.
@ invalid_base64
Base64url decoding failed.
@ invalid_signature
Signature verification failed.
@ invalid_audience
Audience doesn't match expected value.
@ token_expired
Token has expired (exp claim)
@ invalid_issuer
Issuer doesn't match expected value.
@ malformed_token
Token doesn't have 3 dot-separated parts.
@ token_not_yet_valid
Token not yet valid (nbf claim)
@ signature_not_available
OpenSSL not available for verification.
@ unsupported_algorithm
Algorithm not in allowed list.
@ missing_required_claim
Required claim is missing.
@ invalid_json
JSON parsing failed.
std::string_view jwt_error_message(jwt_error error) noexcept
Get human-readable description for a JWT error.
std::optional< std::string > base64url_decode(std::string_view input)
Decode a Base64url-encoded string (RFC 4648 Section 5)
OAuth 2.0 configuration for DICOMweb endpoints.
Decoded JWT claims (payload)
std::string sub
Subject (user identifier)
std::int64_t exp
Expiration time (Unix timestamp)
std::int64_t nbf
Not before (Unix timestamp)
std::vector< std::string > scopes
OAuth 2.0 scopes (from "scope" claim)
std::int64_t iat
Issued at (Unix timestamp)
Decoded JWT header (JOSE header)
std::string typ
Token type (JWT)
std::string kid
Key ID for key selection.
std::string alg
Algorithm (RS256, ES256)
Decoded JWT token with raw segments for signature verification.
std::string signature_bytes
Decoded signature bytes.
std::string header_payload
"header.payload" for signature input
OAuth 2.0 configuration for DICOMweb authorization.