33 : config_(config), validator_(config) {}
36 std::shared_ptr<jwks_provider> provider) {
41 std::shared_ptr<security::access_control_manager> manager) {
46 const crow::request& req, crow::response& res)
const {
78 user.
id = token.claims.sub;
79 user.username = token.claims.sub;
85 if (user_result.is_ok()) {
86 user = user_result.unwrap();
91 set_unauthorized(res,
"Unknown user: not registered in access control system");
102 ctx.set_source_ip(std::string(req.remote_ip_address));
105 return auth_result{std::move(ctx), std::move(token.claims)};
111 std::string_view required_scope)
const {
115 "Insufficient scope: requires " + std::string(required_scope));
124 const std::vector<std::string>& required_scopes)
const {
127 std::string scope_list;
128 for (
size_t i = 0; i < required_scopes.size(); ++i) {
129 if (i > 0) scope_list +=
" or ";
130 scope_list += required_scopes[i];
132 set_forbidden(res,
"Insufficient scope: requires " + scope_list);
151 const crow::request& req)
const {
153 auto auth_header = req.get_header_value(
"Authorization");
154 if (auth_header.empty())
return std::nullopt;
156 std::string_view header_view(auth_header);
159 constexpr std::string_view bearer_prefix =
"Bearer ";
160 if (header_view.size() <= bearer_prefix.size())
return std::nullopt;
163 if (header_view.substr(0, bearer_prefix.size()) != bearer_prefix) {
167 auto token = header_view.substr(bearer_prefix.size());
168 if (token.empty())
return std::nullopt;
177 std::optional<jwk_key> key;
187 if (!key)
return false;
192 }
else if (token.
header.
alg ==
"ES256") {
200 std::string_view message) {
202 res.add_header(
"Content-Type",
"application/json");
203 res.add_header(
"WWW-Authenticate",
"Bearer");
208 std::string_view message) {
210 res.add_header(
"Content-Type",
"application/json");
Represents the security context for a user session.
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.
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.
bool enabled() const noexcept
Check if OAuth 2.0 is enabled.
std::optional< auth_result > authenticate(const crow::request &req, crow::response &res) const
Authenticate a request using OAuth 2.0 Bearer token.
std::shared_ptr< jwks_provider > jwks_provider_
bool require_any_scope(const jwt_claims &claims, crow::response &res, const std::vector< std::string > &required_scopes) const
Check if the request has any of the required scopes.
static void set_unauthorized(crow::response &res, std::string_view message)
Set 401 Unauthorized response.
bool require_scope(const jwt_claims &claims, crow::response &res, std::string_view required_scope) const
Check if the authenticated request has a required scope.
std::optional< std::string_view > extract_bearer_token(const crow::request &req) const
Extract Bearer token from Authorization header.
void set_jwks_provider(std::shared_ptr< jwks_provider > provider)
Set the JWKS provider for signature verification.
bool verify_signature(const jwt_token &token) const
Verify token signature using JWKS keys.
void set_access_control_manager(std::shared_ptr< security::access_control_manager > manager)
Set the access control manager for RBAC integration.
oauth2_middleware(const oauth2_config &config)
Construct middleware with OAuth 2.0 configuration.
static void set_forbidden(crow::response &res, std::string_view message)
Set 403 Forbidden response.
const jwt_validator & validator() const noexcept
Get the underlying JWT validator.
std::shared_ptr< security::access_control_manager > security_manager_
@ Viewer
Read-only access to studies.
std::string_view jwt_error_message(jwt_error error) noexcept
Get human-readable description for a JWT error.
std::string make_error_json(std::string_view code, std::string_view message)
Create JSON error response body with details.
OAuth 2.0 middleware for DICOMweb endpoint authorization.
Common types and utilities for REST API.
Role definitions for RBAC.
Represents a user in the system.
Result of a successful OAuth 2.0 authentication.
Decoded JWT claims (payload)
Decoded JWT token with raw segments for signature verification.
OAuth 2.0 configuration for DICOMweb authorization.
bool enabled
Enable OAuth 2.0 authorization (disabled by default for backward compat)
bool allow_unknown_users
Allow unknown OAuth users not found in RBAC to access as Viewer When false (default): unknown users r...
User definition for RBAC.
User context for session-based access control.