Mercurial > hg > orthanc
changeset 6243:ec3044e6d41f
added OrthancPluginHttpAuthenticationStatus_Forbidden
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Fri, 11 Jul 2025 16:34:33 +0200 |
| parents | 67f9625abb90 |
| children | f1fe166b21d5 |
| files | OrthancFramework/Sources/HttpServer/HttpServer.cpp OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Plugins/Engine/OrthancPlugins.h OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h OrthancServer/Sources/main.cpp |
| diffstat | 6 files changed, 69 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp Fri Jul 11 13:58:27 2025 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp Fri Jul 11 16:34:33 2025 +0200 @@ -1279,16 +1279,16 @@ if (filter == NULL) { - status = IIncomingHttpRequestFilter::AuthenticationStatus_NotImplemented; + status = IIncomingHttpRequestFilter::AuthenticationStatus_BuiltIn; } else { - status = filter->CheckAuthentication(authenticationPayload, redirection, requestUri, argumentsGET, headers); + status = filter->CheckAuthentication(authenticationPayload, redirection, requestUri, remoteIp, headers, argumentsGET); } switch (status) { - case IIncomingHttpRequestFilter::AuthenticationStatus_NotImplemented: + case IIncomingHttpRequestFilter::AuthenticationStatus_BuiltIn: // This was the only behavior available in Orthanc <= 1.12.8 if (server.IsAuthenticationEnabled() && accessMode == AccessMode_Unauthorized) @@ -1298,7 +1298,7 @@ } break; - case IIncomingHttpRequestFilter::AuthenticationStatus_Success: + case IIncomingHttpRequestFilter::AuthenticationStatus_Granted: break; case IIncomingHttpRequestFilter::AuthenticationStatus_Redirect: @@ -1309,6 +1309,10 @@ output.SendStatus(HttpStatus_401_Unauthorized); return; + case IIncomingHttpRequestFilter::AuthenticationStatus_Forbidden: + output.SendStatus(HttpStatus_403_Forbidden); + return; + default: throw OrthancException(ErrorCode_ParameterOutOfRange); }
--- a/OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h Fri Jul 11 13:58:27 2025 +0200 +++ b/OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h Fri Jul 11 16:34:33 2025 +0200 @@ -33,10 +33,11 @@ public: enum AuthenticationStatus { - AuthenticationStatus_NotImplemented, - AuthenticationStatus_Success, - AuthenticationStatus_Unauthorized, - AuthenticationStatus_Redirect + AuthenticationStatus_BuiltIn, // Use the default HTTP authentication built in Orthanc + AuthenticationStatus_Granted, // Let the REST callback process the request + AuthenticationStatus_Unauthorized, // 401 HTTP status + AuthenticationStatus_Forbidden, // 403 HTTP status + AuthenticationStatus_Redirect // 307 HTTP status }; virtual ~IIncomingHttpRequestFilter() @@ -46,14 +47,15 @@ // New in Orthanc 1.8.1 virtual bool IsValidBearerToken(const std::string& token) const = 0; - // This method corresponds to HTTP authentication + // This method corresponds to HTTP authentication + HTTP authorization virtual AuthenticationStatus CheckAuthentication(std::string& customPayload /* out: payload to provide to "IsAllowed()" */, std::string& redirection /* out: path relative to the root */, - const std::string& uri, - const HttpToolbox::GetArguments& getArguments, - const HttpToolbox::Arguments& httpHeaders) const = 0; + const char* uri, + const char* ip, + const HttpToolbox::Arguments& httpHeaders, + const HttpToolbox::GetArguments& getArguments) const = 0; - // This method corresponds to HTTP authorization + // This method corresponds to HTTP authorization alone virtual bool IsAllowed(HttpMethod method, const char* uri, const char* ip,
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Fri Jul 11 13:58:27 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Fri Jul 11 16:34:33 2025 +0200 @@ -6873,15 +6873,16 @@ IIncomingHttpRequestFilter::AuthenticationStatus OrthancPlugins::CheckAuthentication( std::string& customPayload, std::string& redirection, - const std::string& uri, - const HttpToolbox::GetArguments& getArguments, - const HttpToolbox::Arguments& httpHeaders) const + const char* uri, + const char* ip, + const HttpToolbox::Arguments& httpHeaders, + const HttpToolbox::GetArguments& getArguments) const { boost::shared_lock<boost::shared_mutex> lock(pimpl_->incomingHttpRequestFilterMutex_); if (pimpl_->httpAuthentication_ == NULL) { - return IIncomingHttpRequestFilter::AuthenticationStatus_NotImplemented; + return IIncomingHttpRequestFilter::AuthenticationStatus_BuiltIn; // Use the default authentication of Orthanc } else { @@ -6895,9 +6896,9 @@ PluginMemoryBuffer32 payloadBuffer; PluginMemoryBuffer32 redirectionBuffer; OrthancPluginErrorCode code = pimpl_->httpAuthentication_( - &status, payloadBuffer.GetObject(), redirectionBuffer.GetObject(), uri.c_str(), - getKeys.size(), getKeys.empty() ? NULL : &getKeys[0], getValues.empty() ? NULL : &getValues[0], - headersKeys.size(), headersKeys.empty() ? NULL : &headersKeys[0], headersValues.empty() ? NULL : &headersValues[0]); + &status, payloadBuffer.GetObject(), redirectionBuffer.GetObject(), uri, ip, + headersKeys.size(), headersKeys.empty() ? NULL : &headersKeys[0], headersValues.empty() ? NULL : &headersValues[0], + getKeys.size(), getKeys.empty() ? NULL : &getKeys[0], getValues.empty() ? NULL : &getValues[0]); if (code != OrthancPluginErrorCode_Success) { @@ -6907,13 +6908,16 @@ { switch (status) { - case OrthancPluginHttpAuthenticationStatus_Success: + case OrthancPluginHttpAuthenticationStatus_Granted: payloadBuffer.MoveToString(customPayload); - return IIncomingHttpRequestFilter::AuthenticationStatus_Success; + return IIncomingHttpRequestFilter::AuthenticationStatus_Granted; case OrthancPluginHttpAuthenticationStatus_Unauthorized: return IIncomingHttpRequestFilter::AuthenticationStatus_Unauthorized; + case OrthancPluginHttpAuthenticationStatus_Forbidden: + return IIncomingHttpRequestFilter::AuthenticationStatus_Forbidden; + case OrthancPluginHttpAuthenticationStatus_Redirect: redirectionBuffer.MoveToString(redirection); return IIncomingHttpRequestFilter::AuthenticationStatus_Redirect;
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.h Fri Jul 11 13:58:27 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h Fri Jul 11 16:34:33 2025 +0200 @@ -423,9 +423,10 @@ IIncomingHttpRequestFilter::AuthenticationStatus CheckAuthentication( std::string& customPayload, std::string& redirection, - const std::string& uri, - const HttpToolbox::GetArguments& getArguments, - const HttpToolbox::Arguments& httpHeaders) const; + const char* uri, + const char* ip, + const HttpToolbox::Arguments& httpHeaders, + const HttpToolbox::GetArguments& getArguments) const; }; }
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Fri Jul 11 13:58:27 2025 +0200 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Fri Jul 11 16:34:33 2025 +0200 @@ -1208,9 +1208,10 @@ **/ typedef enum { - OrthancPluginHttpAuthenticationStatus_Success = 0, /*!< The authentication has succeeded */ + OrthancPluginHttpAuthenticationStatus_Granted = 0, /*!< The authentication has been granted */ OrthancPluginHttpAuthenticationStatus_Unauthorized = 1, /*!< The authentication has failed (401 HTTP status) */ - OrthancPluginHttpAuthenticationStatus_Redirect = 2, /*!< Redirect to another path (e.g. for login, 307 HTTP status) */ + OrthancPluginHttpAuthenticationStatus_Forbidden = 2, /*!< The authorization has failed (403 HTTP status) */ + OrthancPluginHttpAuthenticationStatus_Redirect = 3, /*!< Redirect to another path (e.g. for login, 307 HTTP status) */ _OrthancPluginHttpAuthenticationStatus_INTERNAL = 0x7fffffff } OrthancPluginHttpAuthenticationStatus; @@ -10380,23 +10381,24 @@ /** - * @brief Callback to authenticate a HTTP request + * @brief Callback to authenticate a HTTP request. * * Signature of a callback function that authenticates every incoming HTTP. * * @param status The output status of the authentication. - * @param customPayload If status is `OrthancPluginHttpAuthenticationStatus_Success`, + * @param customPayload If status is `OrthancPluginHttpAuthenticationStatus_Granted`, * a custom payload that will be provided to the HTTP authorization callback. * @param redirection If status is `OrthancPluginHttpAuthenticationStatus_Redirect`, * a buffer filled with the path where to redirect the user (typically, a login page). * The path is relative to the root of the Web server of Orthanc. * @param uri The URI of interest (without the possible GET arguments). + * @param ip The IP address of the HTTP client. + * @param headersCount The number of HTTP headers. + * @param headersKeys The keys of the HTTP headers (always converted to low-case). + * @param headersValues The values of the HTTP headers. * @param getCount For a GET request, the number of GET parameters. * @param getKeys For a GET request, the keys of the GET parameters. * @param getValues For a GET request, the values of the GET parameters. - * @param headersCount The number of HTTP headers. - * @param headersKeys The keys of the HTTP headers (always converted to low-case). - * @param headersValues The values of the HTTP headers. * @return 0 if success, other value if error. * @ingroup Callbacks **/ @@ -10405,12 +10407,13 @@ OrthancPluginMemoryBuffer* customPayload, /* out */ OrthancPluginMemoryBuffer* redirection, /* out */ const char* uri, + const char* ip, + uint32_t headersCount, + const char* const* headersKeys, + const char* const* headersValues, uint32_t getCount, const char* const* getKeys, - const char* const* getValues, - uint32_t headersCount, - const char* const* headersKeys, - const char* const* headersValues); + const char* const* getValues); typedef struct @@ -10419,21 +10422,29 @@ } _OrthancPluginHttpAuthentication; /** - * @brief Register a callback to handle HTTP authentication. + * @brief Register a callback to handle HTTP authentication (and + * possibly HTTP authorization). * * This function installs a callback that is executed for each * incoming HTTP request to handle HTTP authentication. At most one * plugin can register such a callback. This gives the opportunity - * to one plugin to validate access tokens (such as a JWT), possibly + * to the plugin to validate access tokens (such as a JWT), possibly * redirecting the user to a login page. The authentication callback * can generate a custom payload that will be provided to the * subsequent REST handling callback. * - * The HTTP authentication callback can notably be used if some + * This HTTP authentication callback can notably be used if some * resource in the REST API must be available for public access, as * soon as the "RemoteAccessAllowed" configuration option is set to * "true". * + * In addition, the callback can handle HTTP authorization + * simultaneously with HTTP authentication, by reporting the + * "OrthancPluginHttpAuthenticationStatus_Forbidden" status. This + * corresponds to callbacks installed using + * OrthancPluginRegisterIncomingHttpRequestFilter2(), but the latter + * callbacks do not provide access to the authentication payload. + * * If one plugin installs a HTTP authentication callback, the * built-in HTTP authentication of Orthanc is disabled. This means * that the "RegisteredUsers" and "AuthenticationEnabled"
--- a/OrthancServer/Sources/main.cpp Fri Jul 11 13:58:27 2025 +0200 +++ b/OrthancServer/Sources/main.cpp Fri Jul 11 16:34:33 2025 +0200 @@ -605,20 +605,21 @@ return true; } - virtual AuthenticationStatus CheckAuthentication(std::string& customPayload, - std::string& redirection, - const std::string& uri, - const HttpToolbox::GetArguments& getArguments, - const HttpToolbox::Arguments& httpHeaders) const ORTHANC_OVERRIDE + virtual AuthenticationStatus CheckAuthentication(std::string& customPayload /* out: payload to provide to "IsAllowed()" */, + std::string& redirection /* out: path relative to the root */, + const char* uri, + const char* ip, + const HttpToolbox::Arguments& httpHeaders, + const HttpToolbox::GetArguments& getArguments) const ORTHANC_OVERRIDE { #if ORTHANC_ENABLE_PLUGINS == 1 if (plugins_ != NULL) { - return plugins_->CheckAuthentication(customPayload, redirection, uri, getArguments, httpHeaders); + return plugins_->CheckAuthentication(customPayload, redirection, uri, ip, httpHeaders, getArguments); } #endif - return AuthenticationStatus_NotImplemented; + return AuthenticationStatus_BuiltIn; } };
