From 34dcd14e90c8df9143d8282910978d8810ae6e44 Mon Sep 17 00:00:00 2001 From: StekPerepolnen Date: Wed, 6 Nov 2024 16:47:36 +0000 Subject: [PATCH 1/7] impersonate --- ydb/mvp/oidc_proxy/oidc_client.cpp | 12 ++ .../oidc_impersonate_start_page_nebius.cpp | 149 ++++++++++++++++++ .../oidc_impersonate_start_page_nebius.h | 48 ++++++ .../oidc_impersonate_stop_page_nebius.cpp | 34 ++++ .../oidc_impersonate_stop_page_nebius.h | 36 +++++ .../oidc_proxy/oidc_protected_page_nebius.cpp | 55 +++++-- ydb/mvp/oidc_proxy/oidc_session_create.cpp | 1 - ydb/mvp/oidc_proxy/oidc_settings.h | 1 + ydb/mvp/oidc_proxy/openid_connect.cpp | 4 + 9 files changed, 328 insertions(+), 12 deletions(-) create mode 100644 ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp create mode 100644 ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h create mode 100644 ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp create mode 100644 ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h diff --git a/ydb/mvp/oidc_proxy/oidc_client.cpp b/ydb/mvp/oidc_proxy/oidc_client.cpp index 29568624e335..34e0bd8f2549 100644 --- a/ydb/mvp/oidc_proxy/oidc_client.cpp +++ b/ydb/mvp/oidc_proxy/oidc_client.cpp @@ -14,6 +14,18 @@ void InitOIDC(NActors::TActorSystem& actorSystem, ) ); + actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( + "/impersonate/start", + actorSystem.Register(new THandlerImpersonateStart(httpProxyId, settings)) + ) + ); + + actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( + "/impersonate/stop", + actorSystem.Register(new THandlerImpersonateStop(httpProxyId, settings)) + ) + ); + actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( "/", actorSystem.Register(new TProtectedPageHandler(httpProxyId, settings)) diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp new file mode 100644 index 000000000000..da800a8cdf05 --- /dev/null +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include "openid_connect.h" +#include "oidc_session_create.h" +#include "oidc_settings.h" + +namespace NMVP { +namespace NOIDC { + +THandlerImpersonateStart::THandlerImpersonateStart(const NActors::TActorId& sender, + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings) + : Sender(sender) + , Request(request) + , HttpProxyId(httpProxyId) + , Settings(settings) +{} + +void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { + NHttp::TUrlParameters urlParameters(Request->URL); + TString serviceAccountId = urlParameters["service_accound_id"]; + + NHttp::THeaders headers(Request->Headers); + LOG_DEBUG_S(ctx, EService::MVP, "Start impersonation process"); + NHttp::TCookies cookies(headers.Get("Cookie")); + TString sessionToken = DecodeToken(cookies, CreateNameSessionCookie(Settings.ClientId)); + + if (sessionToken && serviceAccountId) { + RequestImpersonatedToken(sessionToken, serviceAccountId, ctx); + } else { + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Set("Content-Type", "text/plain"); + httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); + } +} + +void THandlerImpersonateStart::RequestImpersonatedToken(const TString sessionToken, const TString serviceAccountId, const NActors::TActorContext& ctx) { + LOG_DEBUG_S(ctx, EService::MVP, "Request impersonated token"); + NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); + httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); + + TMvpTokenator* tokenator = MVPAppData()->Tokenator; + TString token = ""; + if (tokenator) { + token = tokenator->GetToken(Settings.SessionServiceTokenName); + } + httpRequest->Set("Authorization", token); // Bearer included + TStringBuilder body; + body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" + << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" + << "&subject_token_type=urn:ietf:params:oauth:token-type:session_token" + << "&subject_token=" << sessionToken; + httpRequest->Set<&NHttp::THttpRequest::Body>(body); + + ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + + Become(&THandlerSessionServiceCheckNebius::StateExchange); +} + +void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { + NHttp::THttpOutgoingResponsePtr httpResponse; + if (event->Get()->Error.empty() && event->Get()->Response) { + NHttp::THttpIncomingResponsePtr response = event->Get()->Response; + LOG_DEBUG_S(ctx, EService::MVP, "Incoming response from authorization server: " << response->Status); + if (response->Status == "200") { + TStringBuf jsonError; + NJson::TJsonValue jsonValue; + NJson::TJsonReaderConfig jsonConfig; + if (NJson::ReadJsonTree(response->Body, &jsonConfig, &jsonValue)) { + const NJson::TJsonValue* jsonAccessToken; + if (jsonValue.GetValuePointer("access_token", &jsonAccessToken)) { + TString sessionToken = jsonAccessToken->GetStringRobust(); + ProcessSessionToken(sessionToken, ctx); + return; + } else { + jsonError = "Wrong OIDC provider response: access_token not found"; + } + } else { + jsonError = "Wrong OIDC response"; + } + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Set("Content-Type", "text/plain"); + httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, jsonError); + } else { + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Parse(response->Headers); + httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); + } + } else { + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Set("Content-Type", "text/plain"); + httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); + } + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Die(ctx); +} + +TString THandlerImpersonateStart::ChangeSameSiteFieldInSessionCookie(const TString& cookie) { + const static TStringBuf SameSiteParameter {"SameSite=Lax"}; + size_t n = cookie.find(SameSiteParameter); + if (n == TString::npos) { + return cookie; + } + TStringBuilder cookieBuilder; + cookieBuilder << cookie.substr(0, n); + cookieBuilder << "SameSite=None"; + cookieBuilder << cookie.substr(n + SameSiteParameter.size()); + return cookieBuilder; +} + +void THandlerImpersonateStart::RetryRequestToProtectedResourceAndDie(const NActors::TActorContext& ctx) { + NHttp::THeadersBuilder responseHeaders; + RetryRequestToProtectedResourceAndDie(&responseHeaders, ctx); +} + +void THandlerImpersonateStart::RetryRequestToProtectedResourceAndDie(NHttp::THeadersBuilder* responseHeaders, const NActors::TActorContext& ctx) { + SetCORS(Request, responseHeaders); + responseHeaders->Set("Location", Context.GetRequestedAddress()); + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("302", "Found", *responseHeaders))); + Die(ctx); +} + +void THandlerImpersonateStart::SendUnknownErrorResponseAndDie(const NActors::TActorContext& ctx) { + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Set("Content-Type", "text/html"); + SetCORS(Request, &responseHeaders); + const static TStringBuf BAD_REQUEST_HTML_PAGE = "" + "" + "" + "400 Bad Request" + "" + "" + "" + "
" + "

" + "Unknown error has occurred. Please open the page again" + "

" + "
" + "" + ""; + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("400", "Bad Request", responseHeaders, BAD_REQUEST_HTML_PAGE))); + Die(ctx); +} + +} // NOIDC +} // NMVP diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h new file mode 100644 index 000000000000..938e622d2455 --- /dev/null +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "oidc_settings.h" +#include "context.h" + +namespace NMVP { +namespace NOIDC { + +class THandlerImpersonateStart : public NActors::TActorBootstrapped { +private: + using TBase = NActors::TActorBootstrapped; + +protected: + const NActors::TActorId Sender; + const NHttp::THttpIncomingRequestPtr Request; + NActors::TActorId HttpProxyId; + const TOpenIdConnectSettings Settings; + TContext Context; + +public: + THandlerImpersonateStart(const NActors::TActorId& sender, + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings); + + virtual void RequestSessionToken(const TString&, const NActors::TActorContext&) = 0; + virtual void ProcessSessionToken(const TString& accessToken, const NActors::TActorContext&) = 0; + + void Bootstrap(const NActors::TActorContext& ctx); + void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx); + +protected: + TString ChangeSameSiteFieldInSessionCookie(const TString& cookie); + void RetryRequestToProtectedResourceAndDie(const NActors::TActorContext& ctx); + void RetryRequestToProtectedResourceAndDie(NHttp::THeadersBuilder* responseHeaders, const NActors::TActorContext& ctx); + +private: + void SendUnknownErrorResponseAndDie(const NActors::TActorContext& ctx); +}; + +} // NOIDC +} // NMVP diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp new file mode 100644 index 000000000000..b46792a49acc --- /dev/null +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include "openid_connect.h" +#include "oidc_session_create.h" +#include "oidc_settings.h" + +namespace NMVP { +namespace NOIDC { + +THandlerImpersonateStop::THandlerSessionCreate(const NActors::TActorId& sender, + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings) + : Sender(sender) + , Request(request) + , HttpProxyId(httpProxyId) + , Settings(settings) +{} + +void THandlerImpersonateStop::Bootstrap(const NActors::TActorContext& ctx) { + NHttp::THeadersBuilder responseHeaders;responseHeaders + SetCORS(Request, &responseHeaders); + responseHeaders.Set("Set-Cookie", CreateSecureCookie(Settings.ClientId, sessionToken)); + + NHttp::THttpOutgoingResponsePtr httpResponse; + httpResponse = Request->CreateResponse("200", "OK", responseHeaders); + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Die(ctx); +} + +} // NOIDC +} // NMVP diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h new file mode 100644 index 000000000000..195391977722 --- /dev/null +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "oidc_settings.h" +#include "context.h" + +namespace NMVP { +namespace NOIDC { + +class THandlerImpersonateStop : public NActors::TActorBootstrapped { +private: + using TBase = NActors::TActorBootstrapped; + +protected: + const NActors::TActorId Sender; + const NHttp::THttpIncomingRequestPtr Request; + NActors::TActorId HttpProxyId; + const TOpenIdConnectSettings Settings; + TContext Context; + +public: + THandlerImpersonateStop(const NActors::TActorId& sender, + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings); + + void Bootstrap(const NActors::TActorContext& ctx); +}; + +} // NOIDC +} // NMVP diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp index b4ea27d14749..89bd55694434 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp @@ -19,6 +19,17 @@ THandlerSessionServiceCheckNebius::THandlerSessionServiceCheckNebius(const NActo : THandlerSessionServiceCheck(sender, request, httpProxyId, settings) {} +TString DecodeToken(NHttp::TCookies& cookies, const TString& name) { + TString token; + try { + Base64StrictDecode(cookies.Get(name), value); + } catch (std::exception& e) { + LOG_DEBUG("Base64Decode " << name << " cookie: " << e.what()); + token.clear(); + } + return token; +} + void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorContext& ctx) { NHttp::THeaders headers(Request->Headers); LOG_DEBUG_S(ctx, EService::MVP, "Start OIDC process"); @@ -30,18 +41,15 @@ void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorCo LOG_DEBUG_S(ctx, EService::MVP, "Using session cookie (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); } - - TString sessionToken; - try { - Base64StrictDecode(sessionCookieValue, sessionToken); - } catch (std::exception& e) { - LOG_DEBUG_S(ctx, EService::MVP, "Base64Decode session cookie: " << e.what()); - sessionToken.clear(); - } - + TString sessionToken = DecodeToken(cookies, CreateNameSessionCookie(Settings.ClientId)); if (sessionToken) { - ExchangeSessionToken(sessionToken, ctx); - } else { + TString impersonatedToken = DecodeToken(cookies, CreateNameImpersonatedCookie(Settings.ClientId)); + if (impersonatedToken) { + ExchangeImpersonatedToken(impersonatedToken, sessionToken, ctx); + } else { + ExchangeSessionToken(sessionToken, ctx); + } + } else{ RequestAuthorizationCode(ctx); } } @@ -105,6 +113,31 @@ void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessi Become(&THandlerSessionServiceCheckNebius::StateExchange); } +void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString sessionToken, const TString impersonatedToken, const NActors::TActorContext& ctx) { + LOG_DEBUG_S(ctx, EService::MVP, "Exchange session token"); + NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); + httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); + + TMvpTokenator* tokenator = MVPAppData()->Tokenator; + TString token = ""; + if (tokenator) { + token = tokenator->GetToken(Settings.SessionServiceTokenName); + } + httpRequest->Set("Authorization", token); // Bearer included + TStringBuilder body; + body << "grant_type=urn:ietf:params:oauth:grant-type:impersonation" + << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" + << "&subject_token_type=urn:ietf:params:oauth:token-type:jwt" + << "&subject_token=" << impersonatedToken + << "&actor_token=" << sessionToken + << "&actor_token_type=urn:ietf:params:oauth:token-type:session_token"; + httpRequest->Set<&NHttp::THttpRequest::Body>(body); + + ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + + Become(&THandlerSessionServiceCheckNebius::StateExchange); +} + void THandlerSessionServiceCheckNebius::RequestAuthorizationCode(const NActors::TActorContext& ctx) { LOG_DEBUG_S(ctx, EService::MVP, "Request authorization code"); NHttp::THttpOutgoingResponsePtr httpResponse = GetHttpOutgoingResponsePtr(Request, Settings); diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.cpp b/ydb/mvp/oidc_proxy/oidc_session_create.cpp index 26cd6f3396fc..048967282f3f 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create.cpp @@ -56,7 +56,6 @@ void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { SendUnknownErrorResponseAndDie(ctx); } } - } void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { diff --git a/ydb/mvp/oidc_proxy/oidc_settings.h b/ydb/mvp/oidc_proxy/oidc_settings.h index 0b90caf435b9..b420ffb3012f 100644 --- a/ydb/mvp/oidc_proxy/oidc_settings.h +++ b/ydb/mvp/oidc_proxy/oidc_settings.h @@ -9,6 +9,7 @@ namespace NOIDC { struct TOpenIdConnectSettings { static const inline TString YDB_OIDC_COOKIE = "ydb_oidc_cookie"; static const inline TString SESSION_COOKIE = "session_cookie"; + static const inline TString IMPERSONATED_COOKIE = "impersonated_cookie"; static const inline TString DEFAULT_CLIENT_ID = "yc.oauth.ydb-viewer"; static const inline TString DEFAULT_AUTH_URL_PATH = "/oauth/authorize"; diff --git a/ydb/mvp/oidc_proxy/openid_connect.cpp b/ydb/mvp/oidc_proxy/openid_connect.cpp index 498f44a17351..aa364fd96ca1 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.cpp +++ b/ydb/mvp/oidc_proxy/openid_connect.cpp @@ -111,6 +111,10 @@ TString CreateNameSessionCookie(TStringBuf key) { return "__Host_" + TOpenIdConnectSettings::SESSION_COOKIE + "_" + HexEncode(key); } +TString CreateNameImpersonatedCookie(TStringBuf key) { + return "__Host_" + TOpenIdConnectSettings::IMPERSONATED_COOKIE + "_" + HexEncode(key); +} + const TString& GetAuthCallbackUrl() { static const TString callbackUrl = "/auth/callback"; return callbackUrl; From 2f9736133edbd6beb3a1f0f32f65b32bc119dd9e Mon Sep 17 00:00:00 2001 From: StekPerepolnen Date: Fri, 8 Nov 2024 15:35:53 +0000 Subject: [PATCH 2/7] impersonate --- ydb/mvp/oidc_proxy/mvp.cpp | 1 + ydb/mvp/oidc_proxy/oidc_client.cpp | 24 +- .../oidc_impersonate_start_page_nebius.cpp | 148 +++++----- .../oidc_impersonate_start_page_nebius.h | 45 +-- .../oidc_impersonate_stop_page_nebius.cpp | 31 +- .../oidc_impersonate_stop_page_nebius.h | 29 +- .../oidc_proxy/oidc_protected_page_nebius.cpp | 54 ++-- .../oidc_proxy/oidc_protected_page_nebius.h | 13 +- ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp | 271 ++++++++++++++++++ ydb/mvp/oidc_proxy/oidc_session_create.cpp | 2 + ydb/mvp/oidc_proxy/oidc_settings.cpp | 4 + ydb/mvp/oidc_proxy/oidc_settings.h | 3 + ydb/mvp/oidc_proxy/openid_connect.cpp | 6 + ydb/mvp/oidc_proxy/openid_connect.h | 2 + ydb/mvp/oidc_proxy/ya.make | 2 + 15 files changed, 501 insertions(+), 134 deletions(-) diff --git a/ydb/mvp/oidc_proxy/mvp.cpp b/ydb/mvp/oidc_proxy/mvp.cpp index c66759d46f06..2ec089051388 100644 --- a/ydb/mvp/oidc_proxy/mvp.cpp +++ b/ydb/mvp/oidc_proxy/mvp.cpp @@ -233,6 +233,7 @@ void TMVP::TryGetOidcOptionsFromConfig(const YAML::Node& config) { OpenIdConnectSettings.AuthUrlPath = oidc["auth_url_path"].as(OpenIdConnectSettings.DEFAULT_AUTH_URL_PATH); OpenIdConnectSettings.TokenUrlPath = oidc["token_url_path"].as(OpenIdConnectSettings.DEFAULT_TOKEN_URL_PATH); OpenIdConnectSettings.ExchangeUrlPath = oidc["exchange_url_path"].as(OpenIdConnectSettings.DEFAULT_EXCHANGE_URL_PATH); + OpenIdConnectSettings.ImpersonateUrlPath = oidc["impersonate_url_path"].as(OpenIdConnectSettings.DEFAULT_IMPERSONATE_URL_PATH); Cout << "Started processing allowed_proxy_hosts..." << Endl; for (const std::string& host : oidc["allowed_proxy_hosts"].as>()) { Cout << host << " added to allowed_proxy_hosts" << Endl; diff --git a/ydb/mvp/oidc_proxy/oidc_client.cpp b/ydb/mvp/oidc_proxy/oidc_client.cpp index 34e0bd8f2549..825e1e71259d 100644 --- a/ydb/mvp/oidc_proxy/oidc_client.cpp +++ b/ydb/mvp/oidc_proxy/oidc_client.cpp @@ -1,6 +1,8 @@ #include "oidc_client.h" #include "oidc_protected_page_handler.h" #include "oidc_session_create_handler.h" +#include "oidc_impersonate_start_page_nebius.h" +#include "oidc_impersonate_stop_page_nebius.h" namespace NMVP { namespace NOIDC { @@ -14,17 +16,19 @@ void InitOIDC(NActors::TActorSystem& actorSystem, ) ); - actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( - "/impersonate/start", - actorSystem.Register(new THandlerImpersonateStart(httpProxyId, settings)) - ) - ); + if (settings.AccessServiceType == NMvp::nebius_v1) { + actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( + "/impersonate/start", + actorSystem.Register(new TImpersonateStartPageHandler(httpProxyId, settings)) + ) + ); - actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( - "/impersonate/stop", - actorSystem.Register(new THandlerImpersonateStop(httpProxyId, settings)) - ) - ); + actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( + "/impersonate/stop", + actorSystem.Register(new TImpersonateStopPageHandler(httpProxyId, settings)) + ) + ); + } actorSystem.Send(httpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler( "/", diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp index da800a8cdf05..2785aba9a588 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp @@ -1,45 +1,74 @@ -#include #include #include +#include #include +#include #include "openid_connect.h" #include "oidc_session_create.h" -#include "oidc_settings.h" +#include "oidc_impersonate_start_page_nebius.h" namespace NMVP { namespace NOIDC { THandlerImpersonateStart::THandlerImpersonateStart(const NActors::TActorId& sender, - const NHttp::THttpIncomingRequestPtr& request, - const NActors::TActorId& httpProxyId, - const TOpenIdConnectSettings& settings) + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings) : Sender(sender) , Request(request) , HttpProxyId(httpProxyId) , Settings(settings) {} +TString THandlerImpersonateStart::DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx) { + TString token; + try { + Base64StrictDecode(cookie, token); + } catch (std::exception& e) { + LOG_DEBUG_S(ctx, EService::MVP, "Base64Decode " << cookie << " cookie: " << e.what()); + token.clear(); + } + return token; +} + void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { + LOG_DEBUG_S(ctx, EService::MVP, "Start impersonation process"); NHttp::TUrlParameters urlParameters(Request->URL); - TString serviceAccountId = urlParameters["service_accound_id"]; + TString serviceAccountId = urlParameters["service_account_id"]; NHttp::THeaders headers(Request->Headers); - LOG_DEBUG_S(ctx, EService::MVP, "Start impersonation process"); NHttp::TCookies cookies(headers.Get("Cookie")); - TString sessionToken = DecodeToken(cookies, CreateNameSessionCookie(Settings.ClientId)); - if (sessionToken && serviceAccountId) { - RequestImpersonatedToken(sessionToken, serviceAccountId, ctx); - } else { + TString sessionCookieName = CreateNameSessionCookie(Settings.ClientId); + TStringBuf sessionCookieValue = cookies.Get(sessionCookieName); + if (!sessionCookieValue.Empty()) { + LOG_DEBUG_S(ctx, EService::MVP, "Using session cookie (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); + } + + TString sessionToken = DecodeToken(sessionCookieValue, ctx); + + TString jsonError; + if (sessionToken.empty()) { + jsonError = "Wrong impersonate parameter: session cookie not found"; + } else if (serviceAccountId.empty()) { + jsonError = "Wrong impersonate parameter: account_id not found"; + } + + if (jsonError) { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); - httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); + SetCORS(Request, &responseHeaders); + NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, jsonError); + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Die(ctx); + } else { + RequestImpersonatedToken(sessionToken, serviceAccountId, ctx); } } -void THandlerImpersonateStart::RequestImpersonatedToken(const TString sessionToken, const TString serviceAccountId, const NActors::TActorContext& ctx) { +void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionToken, const TString& serviceAccountId, const NActors::TActorContext& ctx) { LOG_DEBUG_S(ctx, EService::MVP, "Request impersonated token"); - NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); + NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetImpersonateEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); TMvpTokenator* tokenator = MVPAppData()->Tokenator; @@ -48,16 +77,28 @@ void THandlerImpersonateStart::RequestImpersonatedToken(const TString sessionTok token = tokenator->GetToken(Settings.SessionServiceTokenName); } httpRequest->Set("Authorization", token); // Bearer included + TStringBuilder body; - body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" - << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" - << "&subject_token_type=urn:ietf:params:oauth:token-type:session_token" - << "&subject_token=" << sessionToken; + body << "session=" << sessionToken + << "&service_account_id=" << serviceAccountId; httpRequest->Set<&NHttp::THttpRequest::Body>(body); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + Become(&THandlerImpersonateStart::StateWork); +} - Become(&THandlerSessionServiceCheckNebius::StateExchange); +void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersonatedToken, const NActors::TActorContext& ctx) { + TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); + TString impersonatedCookieValue = Base64Encode(impersonatedToken); + LOG_DEBUG_S(ctx, EService::MVP, "Set impersonated cookie: (" << impersonatedCookieName << ": " << NKikimr::MaskTicket(impersonatedCookieValue) << ")"); + + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Set("Set-Cookie", CreateSecureCookie(impersonatedCookieName, impersonatedCookieValue)); + SetCORS(Request, &responseHeaders); + NHttp::THttpOutgoingResponsePtr httpResponse; + httpResponse = Request->CreateResponse("200", "OK", responseHeaders); + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Die(ctx); } void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { @@ -70,79 +111,48 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon NJson::TJsonValue jsonValue; NJson::TJsonReaderConfig jsonConfig; if (NJson::ReadJsonTree(response->Body, &jsonConfig, &jsonValue)) { - const NJson::TJsonValue* jsonAccessToken; - if (jsonValue.GetValuePointer("access_token", &jsonAccessToken)) { - TString sessionToken = jsonAccessToken->GetStringRobust(); - ProcessSessionToken(sessionToken, ctx); + const NJson::TJsonValue* jsonImpersonatedToken; + if (jsonValue.GetValuePointer("impersonation", &jsonImpersonatedToken)) { + TString impersonatedToken = jsonImpersonatedToken->GetStringRobust(); + ProcessImpersonatedToken(impersonatedToken, ctx); return; } else { - jsonError = "Wrong OIDC provider response: access_token not found"; + jsonError = "Wrong OIDC provider response: impersonated token not found"; } } else { jsonError = "Wrong OIDC response"; } NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); + SetCORS(Request, &responseHeaders); httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, jsonError); } else { NHttp::THeadersBuilder responseHeaders; - responseHeaders.Parse(response->Headers); + NHttp::THeaders headers(response->Headers); + if (headers.Has("Content-Type")) { + responseHeaders.Set("Content-Type", headers.Get("Content-Type")); + } + SetCORS(Request, &responseHeaders); httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); } } else { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); + SetCORS(Request, &responseHeaders); httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); } ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); Die(ctx); } -TString THandlerImpersonateStart::ChangeSameSiteFieldInSessionCookie(const TString& cookie) { - const static TStringBuf SameSiteParameter {"SameSite=Lax"}; - size_t n = cookie.find(SameSiteParameter); - if (n == TString::npos) { - return cookie; - } - TStringBuilder cookieBuilder; - cookieBuilder << cookie.substr(0, n); - cookieBuilder << "SameSite=None"; - cookieBuilder << cookie.substr(n + SameSiteParameter.size()); - return cookieBuilder; -} - -void THandlerImpersonateStart::RetryRequestToProtectedResourceAndDie(const NActors::TActorContext& ctx) { - NHttp::THeadersBuilder responseHeaders; - RetryRequestToProtectedResourceAndDie(&responseHeaders, ctx); -} - -void THandlerImpersonateStart::RetryRequestToProtectedResourceAndDie(NHttp::THeadersBuilder* responseHeaders, const NActors::TActorContext& ctx) { - SetCORS(Request, responseHeaders); - responseHeaders->Set("Location", Context.GetRequestedAddress()); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("302", "Found", *responseHeaders))); - Die(ctx); -} +TImpersonateStartPageHandler::TImpersonateStartPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) + : TBase(&TImpersonateStartPageHandler::StateWork) + , HttpProxyId(httpProxyId) + , Settings(settings) +{} -void THandlerImpersonateStart::SendUnknownErrorResponseAndDie(const NActors::TActorContext& ctx) { - NHttp::THeadersBuilder responseHeaders; - responseHeaders.Set("Content-Type", "text/html"); - SetCORS(Request, &responseHeaders); - const static TStringBuf BAD_REQUEST_HTML_PAGE = "" - "" - "" - "400 Bad Request" - "" - "" - "" - "
" - "

" - "Unknown error has occurred. Please open the page again" - "

" - "
" - "" - ""; - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("400", "Bad Request", responseHeaders, BAD_REQUEST_HTML_PAGE))); - Die(ctx); +void TImpersonateStartPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) { + ctx.Register(new THandlerImpersonateStart(event->Sender, event->Get()->Request, HttpProxyId, Settings)); } } // NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h index 938e622d2455..6fca9da17bf7 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h @@ -1,11 +1,5 @@ #pragma once -#include -#include -#include -#include -#include -#include #include "oidc_settings.h" #include "context.h" @@ -24,24 +18,39 @@ class THandlerImpersonateStart : public NActors::TActorBootstrappedGetTypeRewrite()) { + HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); + } + } +}; -private: - void SendUnknownErrorResponseAndDie(const NActors::TActorContext& ctx); +class TImpersonateStartPageHandler : public NActors::TActor { + using TBase = NActors::TActor; + + const NActors::TActorId HttpProxyId; + const TOpenIdConnectSettings Settings; + +public: + TImpersonateStartPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); + void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx); + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + } + } }; } // NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp index b46792a49acc..3fa532a4fabf 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp @@ -1,18 +1,14 @@ -#include -#include -#include -#include #include "openid_connect.h" #include "oidc_session_create.h" -#include "oidc_settings.h" +#include "oidc_impersonate_stop_page_nebius.h" namespace NMVP { namespace NOIDC { -THandlerImpersonateStop::THandlerSessionCreate(const NActors::TActorId& sender, - const NHttp::THttpIncomingRequestPtr& request, - const NActors::TActorId& httpProxyId, - const TOpenIdConnectSettings& settings) +THandlerImpersonateStop::THandlerImpersonateStop(const NActors::TActorId& sender, + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings) : Sender(sender) , Request(request) , HttpProxyId(httpProxyId) @@ -20,9 +16,12 @@ THandlerImpersonateStop::THandlerSessionCreate(const NActors::TActorId& sender, {} void THandlerImpersonateStop::Bootstrap(const NActors::TActorContext& ctx) { - NHttp::THeadersBuilder responseHeaders;responseHeaders + TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); + LOG_DEBUG_S(ctx, EService::MVP, "Clear impersonated cookie: (" << impersonatedCookieName << ")"); + + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Set("Set-Cookie", ClearSecureCookie(impersonatedCookieName)); SetCORS(Request, &responseHeaders); - responseHeaders.Set("Set-Cookie", CreateSecureCookie(Settings.ClientId, sessionToken)); NHttp::THttpOutgoingResponsePtr httpResponse; httpResponse = Request->CreateResponse("200", "OK", responseHeaders); @@ -30,5 +29,15 @@ void THandlerImpersonateStop::Bootstrap(const NActors::TActorContext& ctx) { Die(ctx); } +TImpersonateStopPageHandler::TImpersonateStopPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) + : TBase(&TImpersonateStopPageHandler::StateWork) + , HttpProxyId(httpProxyId) + , Settings(settings) +{} + +void TImpersonateStopPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) { + ctx.Register(new THandlerImpersonateStop(event->Sender, event->Get()->Request, HttpProxyId, Settings)); +} + } // NOIDC } // NMVP diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h index 195391977722..3cbe84b6fd7f 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h @@ -1,11 +1,5 @@ #pragma once -#include -#include -#include -#include -#include -#include #include "oidc_settings.h" #include "context.h" @@ -25,12 +19,29 @@ class THandlerImpersonateStop : public NActors::TActorBootstrapped { + using TBase = NActors::TActor; + + const NActors::TActorId HttpProxyId; + const TOpenIdConnectSettings Settings; + +public: + TImpersonateStopPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); + void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx); + + STFUNC(StateWork) { + switch (ev->GetTypeRewrite()) { + HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + } + } +}; + } // NOIDC } // NMVP diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp index 89bd55694434..c7ed5f5908f1 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp @@ -8,7 +8,6 @@ #include "openid_connect.h" #include "context.h" #include "oidc_protected_page_nebius.h" - namespace NMVP { namespace NOIDC { @@ -19,12 +18,20 @@ THandlerSessionServiceCheckNebius::THandlerSessionServiceCheckNebius(const NActo : THandlerSessionServiceCheck(sender, request, httpProxyId, settings) {} -TString DecodeToken(NHttp::TCookies& cookies, const TString& name) { +TStringBuf THandlerSessionServiceCheckNebius::GetCookie(const NHttp::TCookies& cookies, const TString& cookieName, const NActors::TActorContext& ctx) { + TStringBuf cookieValue = cookies.Get(cookieName); + if (!cookieValue.Empty()) { + LOG_DEBUG_S(ctx, EService::MVP, "Using cookie (" << cookieName << ": " << NKikimr::MaskTicket(cookieValue) << ")"); + } + return cookieValue; +} + +TString THandlerSessionServiceCheckNebius::DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx) { TString token; try { - Base64StrictDecode(cookies.Get(name), value); + Base64StrictDecode(cookie, token); } catch (std::exception& e) { - LOG_DEBUG("Base64Decode " << name << " cookie: " << e.what()); + LOG_DEBUG_S(ctx, EService::MVP, "Base64Decode " << cookie << " cookie: " << e.what()); token.clear(); } return token; @@ -35,17 +42,14 @@ void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorCo LOG_DEBUG_S(ctx, EService::MVP, "Start OIDC process"); NHttp::TCookies cookies(headers.Get("Cookie")); - TString sessionCookieName = CreateNameSessionCookie(Settings.ClientId); - TStringBuf sessionCookieValue = cookies.Get(sessionCookieName); - if (!sessionCookieValue.Empty()) { - LOG_DEBUG_S(ctx, EService::MVP, "Using session cookie (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); - } + TStringBuf sessionCookieValue = GetCookie(cookies, CreateNameSessionCookie(Settings.ClientId), ctx); + TStringBuf impersonatedCookieValue = GetCookie(cookies, CreateNameImpersonatedCookie(Settings.ClientId), ctx); - TString sessionToken = DecodeToken(cookies, CreateNameSessionCookie(Settings.ClientId)); + TString sessionToken = DecodeToken(sessionCookieValue, ctx); if (sessionToken) { - TString impersonatedToken = DecodeToken(cookies, CreateNameImpersonatedCookie(Settings.ClientId)); + TString impersonatedToken = DecodeToken(impersonatedCookieValue, ctx); if (impersonatedToken) { - ExchangeImpersonatedToken(impersonatedToken, sessionToken, ctx); + ExchangeImpersonatedToken(sessionToken, impersonatedToken, ctx); } else { ExchangeSessionToken(sessionToken, ctx); } @@ -64,7 +68,7 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv Die(ctx); } else { NHttp::THttpIncomingResponsePtr response = event->Get()->Response; - LOG_DEBUG_S(ctx, EService::MVP, "Getting access token: " << response->Status); + LOG_DEBUG_S(ctx, EService::MVP, "Getting access token: " << response->Status << " " << response->Message); if (response->Status == "200") { TString iamToken; static const NJson::TJsonReaderConfig JsonConfig; @@ -77,7 +81,12 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv return; } } else if (response->Status == "400" || response->Status == "401") { - RequestAuthorizationCode(ctx); + LOG_DEBUG_S(ctx, EService::MVP, "Getting access token: " << response->Body); + if (tokenExchangeType == ETokenExchangeType::ImpersonatedToken) { + ClearImpersonatedCookie(ctx); + } else { + RequestAuthorizationCode(ctx); + } return; } // don't know what to do, just forward response @@ -92,6 +101,7 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessionToken, const NActors::TActorContext& ctx) { LOG_DEBUG_S(ctx, EService::MVP, "Exchange session token"); + tokenExchangeType = ETokenExchangeType::SessionToken; NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -114,7 +124,8 @@ void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessi } void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString sessionToken, const TString impersonatedToken, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "Exchange session token"); + LOG_DEBUG_S(ctx, EService::MVP, "Exchange impersonated token"); + tokenExchangeType = ETokenExchangeType::ImpersonatedToken; NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -125,7 +136,7 @@ void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString } httpRequest->Set("Authorization", token); // Bearer included TStringBuilder body; - body << "grant_type=urn:ietf:params:oauth:grant-type:impersonation" + body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" << "&subject_token_type=urn:ietf:params:oauth:token-type:jwt" << "&subject_token=" << impersonatedToken @@ -138,6 +149,17 @@ void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString Become(&THandlerSessionServiceCheckNebius::StateExchange); } +void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie(const NActors::TActorContext& ctx) { + TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); + LOG_DEBUG_S(ctx, EService::MVP, "Clear impersonated cookie (" << impersonatedCookieName << ") and retry"); + NHttp::THeadersBuilder responseHeaders; + SetCORS(Request, &responseHeaders); + responseHeaders.Set("Set-Cookie", ClearSecureCookie(impersonatedCookieName)); + responseHeaders.Set("Location", Request->URL); + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("307", "Temporary Redirect", responseHeaders))); + Die(ctx); +} + void THandlerSessionServiceCheckNebius::RequestAuthorizationCode(const NActors::TActorContext& ctx) { LOG_DEBUG_S(ctx, EService::MVP, "Request authorization code"); NHttp::THttpOutgoingResponsePtr httpResponse = GetHttpOutgoingResponsePtr(Request, Settings); diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h index c54aeb700d4d..ed8c04e6d839 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h @@ -9,12 +9,21 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { private: using TBase = THandlerSessionServiceCheck; +protected: + enum class ETokenExchangeType { + SessionToken, + ImpersonatedToken + }; + + ETokenExchangeType tokenExchangeType = ETokenExchangeType::SessionToken; + public: THandlerSessionServiceCheckNebius(const NActors::TActorId& sender, const NHttp::THttpIncomingRequestPtr& request, const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - + TStringBuf GetCookie(const NHttp::TCookies& cookies, const TString& cookieName, const NActors::TActorContext& ctx); + TString DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx); void StartOidcProcess(const NActors::TActorContext& ctx) override; void HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx); @@ -33,6 +42,8 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { private: void ExchangeSessionToken(const TString sessionToken, const NActors::TActorContext& ctx); + void ExchangeImpersonatedToken(const TString sessionToken, const TString impersonatedToken, const NActors::TActorContext& ctx); + void ClearImpersonatedCookie(const NActors::TActorContext& ctx); void RequestAuthorizationCode(const NActors::TActorContext& ctx); void ForwardUserRequest(TStringBuf authHeader, const NActors::TActorContext& ctx, bool secure = false) override; bool NeedSendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response) const override; diff --git a/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp b/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp index 68ff53dccb2f..53c27dd80358 100644 --- a/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp +++ b/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp @@ -8,6 +8,8 @@ #include #include "oidc_protected_page_handler.h" #include "oidc_session_create_handler.h" +#include "oidc_impersonate_start_page_nebius.h" +#include "oidc_impersonate_stop_page_nebius.h" #include "oidc_settings.h" #include "openid_connect.h" #include "context.h" @@ -1126,4 +1128,273 @@ Y_UNIT_TEST_SUITE(Mvp) { UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Status, "400"); UNIT_ASSERT_STRING_CONTAINS(outgoingResponseEv->Response->Body, "Unknown error has occurred. Please open the page again"); } + + Y_UNIT_TEST(OidcImpersonationStartFlow) { + TPortManager tp; + ui16 sessionServicePort = tp.GetPort(8655); + TMvpTestRuntime runtime; + runtime.Initialize(); + + TOpenIdConnectSettings settings { + .ClientId = "client_id", + .SessionServiceEndpoint = "localhost:" + ToString(sessionServicePort), + .AuthorizationServerAddress = "https://auth.test.net", + .ClientSecret = "0123456789abcdef", + .AccessServiceType = NMvp::nebius_v1 + }; + + const NActors::TActorId edge = runtime.AllocateEdgeActor(); + + TSessionServiceMock sessionServiceMock; + sessionServiceMock.AllowedAccessTokens.insert("valid_access_token"); + grpc::ServerBuilder builder; + builder.AddListeningPort(settings.SessionServiceEndpoint, grpc::InsecureServerCredentials()).RegisterService(&sessionServiceMock); + std::unique_ptr sessionServer(builder.BuildAndStart()); + + const NActors::TActorId impersonateStart = runtime.Register(new TImpersonateStartPageHandler(edge, settings)); + const TString hostProxy = "oidcproxy.net"; + TStringBuilder request; + request << "GET /impersonate/start?service_account_id=serviceaccount-e0tydb-dev HTTP/1.1\r\n" + << "Host: " + hostProxy + "\r\n" + << "Cookie: " << CreateNameSessionCookie(settings.ClientId) + "=" + Base64Encode("session_cookie") + "\r\n\r\n"; + + NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest(); + EatWholeString(incomingRequest, request); + incomingRequest->Endpoint->Secure = true; + runtime.Send(new IEventHandle(impersonateStart, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest))); + + TAutoPtr handle; + auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->Host, "auth.test.net"); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->URL, "/oauth2/impersonation/impersonate"); + UNIT_ASSERT_EQUAL(outgoingRequestEv->Request->Secure, true); + NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); + TString okResponseBody {"{\"impersonation\": \"impersonation_token\"}"}; + EatWholeString(incomingResponse, "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n" + "Content-Type: text/html\r\n" + "Content-Length: " + ToString(okResponseBody.size()) + "\r\n\r\n" + okResponseBody); + runtime.Send(new IEventHandle(handle->Sender, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(outgoingRequestEv->Request, incomingResponse))); + + NHttp::TEvHttpProxy::TEvHttpOutgoingResponse* outgoingResponseEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Status, "200"); + const NHttp::THeaders impersonatePageHeaders(outgoingResponseEv->Response->Headers); + UNIT_ASSERT(impersonatePageHeaders.Has("Set-Cookie")); + TStringBuf impersonatedCookie = impersonatePageHeaders.Get("Set-Cookie"); + TString expectedCookie = CreateSecureCookie(CreateNameImpersonatedCookie(settings.ClientId), Base64Encode("impersonation_token")); + UNIT_ASSERT_STRINGS_EQUAL(impersonatedCookie, expectedCookie); + } + + Y_UNIT_TEST(OidcImpersonationStartNeedServiceAccountId) { + TPortManager tp; + ui16 sessionServicePort = tp.GetPort(8655); + TMvpTestRuntime runtime; + runtime.Initialize(); + + TOpenIdConnectSettings settings { + .ClientId = "client_id", + .SessionServiceEndpoint = "localhost:" + ToString(sessionServicePort), + .AuthorizationServerAddress = "https://auth.test.net", + .ClientSecret = "0123456789abcdef", + .AccessServiceType = NMvp::nebius_v1 + }; + + const NActors::TActorId edge = runtime.AllocateEdgeActor(); + + TSessionServiceMock sessionServiceMock; + sessionServiceMock.AllowedAccessTokens.insert("valid_access_token"); + grpc::ServerBuilder builder; + builder.AddListeningPort(settings.SessionServiceEndpoint, grpc::InsecureServerCredentials()).RegisterService(&sessionServiceMock); + std::unique_ptr sessionServer(builder.BuildAndStart()); + + const NActors::TActorId impersonateStart = runtime.Register(new TImpersonateStartPageHandler(edge, settings)); + const TString hostProxy = "oidcproxy.net"; + TStringBuilder request; + request << "GET /impersonate/start HTTP/1.1\r\n" + << "Host: " + hostProxy + "\r\n" + << "Cookie: " << CreateNameSessionCookie(settings.ClientId) + "=" + Base64Encode("session_cookie") + "\r\n\r\n"; + + NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest(); + EatWholeString(incomingRequest, request); + incomingRequest->Endpoint->Secure = true; + runtime.Send(new IEventHandle(impersonateStart, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest))); + + TAutoPtr handle; + NHttp::TEvHttpProxy::TEvHttpOutgoingResponse* outgoingResponseEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Status, "400"); + const NHttp::THeaders impersonatePageHeaders(outgoingResponseEv->Response->Headers); + UNIT_ASSERT(!impersonatePageHeaders.Has("Set-Cookie")); + } + + Y_UNIT_TEST(OidcImpersonationStopFlow) { + TPortManager tp; + ui16 sessionServicePort = tp.GetPort(8655); + TMvpTestRuntime runtime; + runtime.Initialize(); + + TOpenIdConnectSettings settings { + .ClientId = "client_id", + .SessionServiceEndpoint = "localhost:" + ToString(sessionServicePort), + .AuthorizationServerAddress = "https://auth.test.net", + .ClientSecret = "0123456789abcdef", + .AccessServiceType = NMvp::nebius_v1 + }; + + const NActors::TActorId edge = runtime.AllocateEdgeActor(); + + TSessionServiceMock sessionServiceMock; + sessionServiceMock.AllowedAccessTokens.insert("valid_access_token"); + grpc::ServerBuilder builder; + builder.AddListeningPort(settings.SessionServiceEndpoint, grpc::InsecureServerCredentials()).RegisterService(&sessionServiceMock); + std::unique_ptr sessionServer(builder.BuildAndStart()); + + const NActors::TActorId impersonateStop = runtime.Register(new TImpersonateStopPageHandler(edge, settings)); + const TString hostProxy = "oidcproxy.net"; + TStringBuilder request; + request << "GET /impersonate/start HTTP/1.1\r\n" + << "Host: " + hostProxy + "\r\n" + << "Cookie: " << CreateNameImpersonatedCookie(settings.ClientId) + "=" + Base64Encode("impersonated_cookie") + "\r\n\r\n"; + + NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest(); + EatWholeString(incomingRequest, request); + incomingRequest->Endpoint->Secure = true; + runtime.Send(new IEventHandle(impersonateStop, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest))); + + TAutoPtr handle; + NHttp::TEvHttpProxy::TEvHttpOutgoingResponse* outgoingResponseEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Status, "200"); + const NHttp::THeaders impersonatePageHeaders(outgoingResponseEv->Response->Headers); + UNIT_ASSERT(impersonatePageHeaders.Has("Set-Cookie")); + TStringBuf impersonatedCookie = impersonatePageHeaders.Get("Set-Cookie"); + TString expectedCookie = ClearSecureCookie(CreateNameImpersonatedCookie(settings.ClientId)); + UNIT_ASSERT_STRINGS_EQUAL(impersonatedCookie, expectedCookie); + } + + Y_UNIT_TEST(OidcImpersonatedAccessToProtectedResource) { + TPortManager tp; + ui16 sessionServicePort = tp.GetPort(8655); + TMvpTestRuntime runtime; + runtime.Initialize(); + + const TString allowedProxyHost {"ydb.viewer.page"}; + TOpenIdConnectSettings settings { + .ClientId = "client_id", + .SessionServiceEndpoint = "localhost:" + ToString(sessionServicePort), + .AuthorizationServerAddress = "https://auth.test.net", + .ClientSecret = "0123456789abcdef", + .AllowedProxyHosts = {allowedProxyHost}, + .AccessServiceType = NMvp::nebius_v1 + }; + + const NActors::TActorId edge = runtime.AllocateEdgeActor(); + TSessionServiceMock sessionServiceMock; + sessionServiceMock.AllowedAccessTokens.insert("valid_access_token"); + grpc::ServerBuilder builder; + builder.AddListeningPort(settings.SessionServiceEndpoint, grpc::InsecureServerCredentials()).RegisterService(&sessionServiceMock); + std::unique_ptr sessionServer(builder.BuildAndStart()); + + const NActors::TActorId impersonateStart = runtime.Register(new TProtectedPageHandler(edge, settings)); + const TString hostProxy = "oidcproxy.net"; + const TString protectedPage = "/" + allowedProxyHost + "/counters"; + TStringBuilder request; + request << "GET " << protectedPage << " HTTP/1.1\r\n" + << "Host: " << hostProxy << "\r\n" + << "Referer: https://" << hostProxy << protectedPage << "\r\n" + << "Cookie: " << CreateNameSessionCookie(settings.ClientId) << "=" << Base64Encode("session_cookie") << "; " + << CreateNameImpersonatedCookie(settings.ClientId) << "=" << Base64Encode("impersonated_cookie") << "\r\n\r\n"; + NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest(); + EatWholeString(incomingRequest, request); + incomingRequest->Endpoint->Secure = true; + runtime.Send(new IEventHandle(impersonateStart, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest))); + + TAutoPtr handle; + auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->Host, "auth.test.net"); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->URL, "/oauth2/session/exchange"); + + UNIT_ASSERT_EQUAL(outgoingRequestEv->Request->Secure, true); + NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); + TString okResponseBody {"{\"access_token\": \"access_token\"}"}; + EatWholeString(incomingResponse, "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n" + "Content-Type: text/html\r\n" + "Content-Length: " + ToString(okResponseBody.size()) + "\r\n\r\n" + okResponseBody); + runtime.Send(new IEventHandle(handle->Sender, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(outgoingRequestEv->Request, incomingResponse))); + + outgoingRequestEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->Host, allowedProxyHost); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->URL, "/counters"); + UNIT_ASSERT_STRING_CONTAINS(outgoingRequestEv->Request->Headers, "Authorization: Bearer access_token"); + UNIT_ASSERT_EQUAL(outgoingRequestEv->Request->Secure, false); + incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); + okResponseBody = "this is test"; + EatWholeString(incomingResponse, "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n" + "Content-Type: text/html\r\n" + "Content-Length: " + ToString(okResponseBody.size()) + "\r\n\r\n" + okResponseBody); + + runtime.Send(new IEventHandle(handle->Sender, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(outgoingRequestEv->Request, incomingResponse))); + auto outgoingResponseEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Status, "200"); + UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Body, "this is test"); + } + + Y_UNIT_TEST(OidcImpersonatedAccessNotAuthorized) { + TPortManager tp; + ui16 sessionServicePort = tp.GetPort(8655); + TMvpTestRuntime runtime; + runtime.Initialize(); + + const TString allowedProxyHost {"ydb.viewer.page"}; + TOpenIdConnectSettings settings { + .ClientId = "client_id", + .SessionServiceEndpoint = "localhost:" + ToString(sessionServicePort), + .AuthorizationServerAddress = "https://auth.test.net", + .ClientSecret = "0123456789abcdef", + .AllowedProxyHosts = {allowedProxyHost}, + .AccessServiceType = NMvp::nebius_v1 + }; + + const NActors::TActorId edge = runtime.AllocateEdgeActor(); + TSessionServiceMock sessionServiceMock; + sessionServiceMock.AllowedAccessTokens.insert("valid_access_token"); + grpc::ServerBuilder builder; + builder.AddListeningPort(settings.SessionServiceEndpoint, grpc::InsecureServerCredentials()).RegisterService(&sessionServiceMock); + std::unique_ptr sessionServer(builder.BuildAndStart()); + + const NActors::TActorId impersonateStart = runtime.Register(new TProtectedPageHandler(edge, settings)); + const TString hostProxy = "oidcproxy.net"; + const TString protectedPage = "/" + allowedProxyHost + "/counters"; + TStringBuilder request; + request << "GET " << protectedPage << " HTTP/1.1\r\n" + << "Host: " << hostProxy << "\r\n" + << "Referer: https://" << hostProxy << protectedPage << "\r\n" + << "Cookie: " << CreateNameSessionCookie(settings.ClientId) << "=" << Base64Encode("session_cookie") << "; " + << CreateNameImpersonatedCookie(settings.ClientId) << "=" << Base64Encode("impersonated_cookie") << "\r\n\r\n"; + NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest(); + EatWholeString(incomingRequest, request); + incomingRequest->Endpoint->Secure = true; + runtime.Send(new IEventHandle(impersonateStart, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest))); + + TAutoPtr handle; + auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->Host, "auth.test.net"); + UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->URL, "/oauth2/session/exchange"); + + UNIT_ASSERT_EQUAL(outgoingRequestEv->Request->Secure, true); + NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); + TString okResponseBody {"{\"error\": \"bad_token\"}"}; + EatWholeString(incomingResponse, "HTTP/1.1 401 OK\r\n" + "Connection: close\r\n" + "Content-Type: text/html\r\n" + "Content-Length: " + ToString(okResponseBody.size()) + "\r\n\r\n" + okResponseBody); + runtime.Send(new IEventHandle(handle->Sender, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(outgoingRequestEv->Request, incomingResponse))); + + auto outgoingResponseEv = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Status, "307"); + const NHttp::THeaders headers(outgoingResponseEv->Response->Headers); + UNIT_ASSERT(headers.Has("Location")); + TStringBuf location = headers.Get("Location"); + UNIT_ASSERT_STRINGS_EQUAL(location, protectedPage); + } } diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.cpp b/ydb/mvp/oidc_proxy/oidc_session_create.cpp index 048967282f3f..9f5670538579 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create.cpp @@ -20,6 +20,7 @@ THandlerSessionCreate::THandlerSessionCreate(const NActors::TActorId& sender, {} void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { + LOG_DEBUG_S(ctx, NMVP::EService::MVP, "Restore oidc session"); NHttp::TUrlParameters urlParameters(Request->URL); TString code = urlParameters["code"]; TString state = urlParameters["state"]; @@ -56,6 +57,7 @@ void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { SendUnknownErrorResponseAndDie(ctx); } } + } void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { diff --git a/ydb/mvp/oidc_proxy/oidc_settings.cpp b/ydb/mvp/oidc_proxy/oidc_settings.cpp index 49ec00fa467a..81c8645d36ce 100644 --- a/ydb/mvp/oidc_proxy/oidc_settings.cpp +++ b/ydb/mvp/oidc_proxy/oidc_settings.cpp @@ -21,5 +21,9 @@ TString TOpenIdConnectSettings::GetExchangeEndpointURL() const { return AuthorizationServerAddress + ExchangeUrlPath; } +TString TOpenIdConnectSettings::GetImpersonateEndpointURL() const { + return AuthorizationServerAddress + ImpersonateUrlPath; +} + } // NOIDC } // NMVP diff --git a/ydb/mvp/oidc_proxy/oidc_settings.h b/ydb/mvp/oidc_proxy/oidc_settings.h index b420ffb3012f..878f3d1ba68c 100644 --- a/ydb/mvp/oidc_proxy/oidc_settings.h +++ b/ydb/mvp/oidc_proxy/oidc_settings.h @@ -15,6 +15,7 @@ struct TOpenIdConnectSettings { static const inline TString DEFAULT_AUTH_URL_PATH = "/oauth/authorize"; static const inline TString DEFAULT_TOKEN_URL_PATH = "/oauth/token"; static const inline TString DEFAULT_EXCHANGE_URL_PATH = "/oauth2/session/exchange"; + static const inline TString DEFAULT_IMPERSONATE_URL_PATH = "/oauth2/impersonation/impersonate"; TString ClientId = DEFAULT_CLIENT_ID; TString SessionServiceEndpoint; @@ -27,11 +28,13 @@ struct TOpenIdConnectSettings { TString AuthUrlPath = DEFAULT_AUTH_URL_PATH; TString TokenUrlPath = DEFAULT_TOKEN_URL_PATH; TString ExchangeUrlPath = DEFAULT_EXCHANGE_URL_PATH; + TString ImpersonateUrlPath = DEFAULT_IMPERSONATE_URL_PATH; TString GetAuthorizationString() const; TString GetAuthEndpointURL() const; TString GetTokenEndpointURL() const; TString GetExchangeEndpointURL() const; + TString GetImpersonateEndpointURL() const; }; } // NOIDC diff --git a/ydb/mvp/oidc_proxy/openid_connect.cpp b/ydb/mvp/oidc_proxy/openid_connect.cpp index aa364fd96ca1..1ee181a4d5e8 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.cpp +++ b/ydb/mvp/oidc_proxy/openid_connect.cpp @@ -127,6 +127,12 @@ TString CreateSecureCookie(const TString& name, const TString& value) { return cookieBuilder; } +TString ClearSecureCookie(const TString& name) { + TStringBuilder cookieBuilder; + cookieBuilder << name << "=; Path=/; Secure; HttpOnly; SameSite=None; Partitioned; Max-Age=0"; + return cookieBuilder; +} + TRestoreOidcContextResult RestoreOidcContext(const NHttp::TCookies& cookies, const TString& key) { TStringBuilder errorMessage; errorMessage << "Restore oidc context failed: "; diff --git a/ydb/mvp/oidc_proxy/openid_connect.h b/ydb/mvp/oidc_proxy/openid_connect.h index 4cf7cf30196d..a8093a639726 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.h +++ b/ydb/mvp/oidc_proxy/openid_connect.h @@ -45,8 +45,10 @@ void SetHeader(NYdbGrpc::TCallMeta& meta, const TString& name, const TString& va NHttp::THttpOutgoingResponsePtr GetHttpOutgoingResponsePtr(const NHttp::THttpIncomingRequestPtr& request, const TOpenIdConnectSettings& settings); TString CreateNameYdbOidcCookie(TStringBuf key, TStringBuf state); TString CreateNameSessionCookie(TStringBuf key); +TString CreateNameImpersonatedCookie(TStringBuf key); const TString& GetAuthCallbackUrl(); TString CreateSecureCookie(const TString& name, const TString& value); +TString ClearSecureCookie(const TString& name); void SetCORS(const NHttp::THttpIncomingRequestPtr& request, NHttp::THeadersBuilder* const headers); TRestoreOidcContextResult RestoreOidcContext(const NHttp::TCookies& cookies, const TString& key); TCheckStateResult CheckState(const TString& state, const TString& key); diff --git a/ydb/mvp/oidc_proxy/ya.make b/ydb/mvp/oidc_proxy/ya.make index 4158e8f78783..61b522f75634 100644 --- a/ydb/mvp/oidc_proxy/ya.make +++ b/ydb/mvp/oidc_proxy/ya.make @@ -10,6 +10,8 @@ SRCS( oidc_client.cpp openid_connect.cpp oidc_settings.cpp + oidc_impersonate_start_page_nebius.cpp + oidc_impersonate_stop_page_nebius.cpp oidc_protected_page_handler.cpp oidc_protected_page_yandex.cpp oidc_protected_page_nebius.cpp From 62ab8ab61f71f53b0a97cd844725b7eed0098191 Mon Sep 17 00:00:00 2001 From: StekPerepolnen Date: Wed, 20 Nov 2024 12:38:44 +0000 Subject: [PATCH 3/7] remove unnecessary --- .../oidc_impersonate_start_page_nebius.cpp | 11 ----- .../oidc_impersonate_start_page_nebius.h | 2 - .../oidc_impersonate_stop_page_nebius.h | 1 - .../oidc_proxy/oidc_protected_page_nebius.cpp | 44 +++++-------------- .../oidc_proxy/oidc_protected_page_nebius.h | 3 +- ydb/mvp/oidc_proxy/openid_connect.cpp | 11 +++++ ydb/mvp/oidc_proxy/openid_connect.h | 2 +- 7 files changed, 25 insertions(+), 49 deletions(-) diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp index 2785aba9a588..54880d0cf468 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp @@ -20,17 +20,6 @@ THandlerImpersonateStart::THandlerImpersonateStart(const NActors::TActorId& send , Settings(settings) {} -TString THandlerImpersonateStart::DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx) { - TString token; - try { - Base64StrictDecode(cookie, token); - } catch (std::exception& e) { - LOG_DEBUG_S(ctx, EService::MVP, "Base64Decode " << cookie << " cookie: " << e.what()); - token.clear(); - } - return token; -} - void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { LOG_DEBUG_S(ctx, EService::MVP, "Start impersonation process"); NHttp::TUrlParameters urlParameters(Request->URL); diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h index 6fca9da17bf7..37a332a7689f 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h @@ -15,10 +15,8 @@ class THandlerImpersonateStart : public NActors::TActorBootstrappedHeaders); LOG_DEBUG_S(ctx, EService::MVP, "Start OIDC process"); @@ -99,9 +88,8 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv } } -void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessionToken, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "Exchange session token"); - tokenExchangeType = ETokenExchangeType::SessionToken; +void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx) { + tokenExchangeType = exchangeType; NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -111,30 +99,25 @@ void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessi token = tokenator->GetToken(Settings.SessionServiceTokenName); } httpRequest->Set("Authorization", token); // Bearer included + httpRequest->Set<&NHttp::THttpRequest::Body>(body); + + ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + Become(&THandlerSessionServiceCheckNebius::StateExchange); +} + +void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessionToken, const NActors::TActorContext& ctx) { + LOG_DEBUG_S(ctx, EService::MVP, "Exchange session token"); TStringBuilder body; body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" << "&subject_token_type=urn:ietf:params:oauth:token-type:session_token" << "&subject_token=" << sessionToken; - httpRequest->Set<&NHttp::THttpRequest::Body>(body); - - ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); - Become(&THandlerSessionServiceCheckNebius::StateExchange); + SendTokenExchangeRequest(body, ETokenExchangeType::SessionToken, ctx); } void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString sessionToken, const TString impersonatedToken, const NActors::TActorContext& ctx) { LOG_DEBUG_S(ctx, EService::MVP, "Exchange impersonated token"); - tokenExchangeType = ETokenExchangeType::ImpersonatedToken; - NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); - httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); - - TMvpTokenator* tokenator = MVPAppData()->Tokenator; - TString token = ""; - if (tokenator) { - token = tokenator->GetToken(Settings.SessionServiceTokenName); - } - httpRequest->Set("Authorization", token); // Bearer included TStringBuilder body; body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" @@ -142,11 +125,8 @@ void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString << "&subject_token=" << impersonatedToken << "&actor_token=" << sessionToken << "&actor_token_type=urn:ietf:params:oauth:token-type:session_token"; - httpRequest->Set<&NHttp::THttpRequest::Body>(body); - ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); - - Become(&THandlerSessionServiceCheckNebius::StateExchange); + SendTokenExchangeRequest(body, ETokenExchangeType::ImpersonatedToken, ctx); } void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie(const NActors::TActorContext& ctx) { diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h index ed8c04e6d839..d80cc29474e8 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h @@ -23,7 +23,6 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); TStringBuf GetCookie(const NHttp::TCookies& cookies, const TString& cookieName, const NActors::TActorContext& ctx); - TString DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx); void StartOidcProcess(const NActors::TActorContext& ctx) override; void HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx); @@ -40,7 +39,7 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { } private: - + void SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx); void ExchangeSessionToken(const TString sessionToken, const NActors::TActorContext& ctx); void ExchangeImpersonatedToken(const TString sessionToken, const TString impersonatedToken, const NActors::TActorContext& ctx); void ClearImpersonatedCookie(const NActors::TActorContext& ctx); diff --git a/ydb/mvp/oidc_proxy/openid_connect.cpp b/ydb/mvp/oidc_proxy/openid_connect.cpp index 1ee181a4d5e8..de68c3113ca1 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.cpp +++ b/ydb/mvp/oidc_proxy/openid_connect.cpp @@ -237,5 +237,16 @@ TCheckStateResult CheckState(const TString& state, const TString& key) { return TCheckStateResult(); } +TString DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx) { + TString token; + try { + Base64StrictDecode(cookie, token); + } catch (std::exception& e) { + LOG_DEBUG_S(ctx, EService::MVP, "Base64Decode " << cookie << " cookie: " << e.what()); + token.clear(); + } + return token; +} + } // NOIDC } // NMVP diff --git a/ydb/mvp/oidc_proxy/openid_connect.h b/ydb/mvp/oidc_proxy/openid_connect.h index a8093a639726..3706417b0c2b 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.h +++ b/ydb/mvp/oidc_proxy/openid_connect.h @@ -9,7 +9,6 @@ #include #include "context.h" - namespace NMVP { namespace NOIDC { @@ -52,6 +51,7 @@ TString ClearSecureCookie(const TString& name); void SetCORS(const NHttp::THttpIncomingRequestPtr& request, NHttp::THeadersBuilder* const headers); TRestoreOidcContextResult RestoreOidcContext(const NHttp::TCookies& cookies, const TString& key); TCheckStateResult CheckState(const TString& state, const TString& key); +TString DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx); template std::unique_ptr> CreateGRpcServiceConnection(const TString& endpoint) { From 767932d6304b319afe75bf263bc95b77b3474944 Mon Sep 17 00:00:00 2001 From: StekPerepolnen Date: Wed, 20 Nov 2024 19:42:17 +0000 Subject: [PATCH 4/7] rename variables --- ydb/mvp/oidc_proxy/context.cpp | 6 +- ydb/mvp/oidc_proxy/context.h | 6 +- ydb/mvp/oidc_proxy/mvp.cpp | 6 +- ydb/mvp/oidc_proxy/mvp.h | 6 +- ydb/mvp/oidc_proxy/oidc_client.cpp | 8 +- ydb/mvp/oidc_proxy/oidc_client.h | 6 +- .../oidc_impersonate_start_page_nebius.cpp | 83 +++++++------ .../oidc_impersonate_start_page_nebius.h | 17 +-- .../oidc_impersonate_stop_page_nebius.cpp | 19 +-- .../oidc_impersonate_stop_page_nebius.h | 10 +- ydb/mvp/oidc_proxy/oidc_protected_page.cpp | 35 +++--- ydb/mvp/oidc_proxy/oidc_protected_page.h | 11 +- .../oidc_protected_page_handler.cpp | 6 +- .../oidc_proxy/oidc_protected_page_handler.h | 9 +- .../oidc_proxy/oidc_protected_page_nebius.cpp | 112 ++++++++---------- .../oidc_proxy/oidc_protected_page_nebius.h | 15 +-- .../oidc_proxy/oidc_protected_page_yandex.cpp | 10 +- .../oidc_proxy/oidc_protected_page_yandex.h | 9 +- ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp | 17 +-- ydb/mvp/oidc_proxy/oidc_session_create.cpp | 28 ++--- ydb/mvp/oidc_proxy/oidc_session_create.h | 9 +- .../oidc_session_create_handler.cpp | 6 +- .../oidc_proxy/oidc_session_create_handler.h | 9 +- .../oidc_proxy/oidc_session_create_nebius.cpp | 17 +-- .../oidc_proxy/oidc_session_create_nebius.h | 9 +- .../oidc_proxy/oidc_session_create_yandex.cpp | 14 +-- .../oidc_proxy/oidc_session_create_yandex.h | 9 +- ydb/mvp/oidc_proxy/oidc_settings.cpp | 6 +- ydb/mvp/oidc_proxy/oidc_settings.h | 6 +- ydb/mvp/oidc_proxy/openid_connect.cpp | 19 ++- ydb/mvp/oidc_proxy/openid_connect.h | 9 +- 31 files changed, 262 insertions(+), 270 deletions(-) diff --git a/ydb/mvp/oidc_proxy/context.cpp b/ydb/mvp/oidc_proxy/context.cpp index fb5ebae81342..f348216a4ea5 100644 --- a/ydb/mvp/oidc_proxy/context.cpp +++ b/ydb/mvp/oidc_proxy/context.cpp @@ -7,8 +7,7 @@ #include "oidc_settings.h" #include "context.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { TContext::TContext(const TInitializer& initializer) : State(initializer.State) @@ -94,5 +93,4 @@ TStringBuf TContext::GetRequestedUrl(const NHttp::THttpIncomingRequestPtr& reque return requestedUrl; } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/context.h b/ydb/mvp/oidc_proxy/context.h index 93962816f5a2..1719e3063ef1 100644 --- a/ydb/mvp/oidc_proxy/context.h +++ b/ydb/mvp/oidc_proxy/context.h @@ -10,8 +10,7 @@ using THttpIncomingRequestPtr = TIntrusivePtr; } -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { class TContext { public: @@ -45,5 +44,4 @@ class TContext { TString GenerateCookie(const TString& key) const; }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/mvp.cpp b/ydb/mvp/oidc_proxy/mvp.cpp index 2ec089051388..fb5171b87c0a 100644 --- a/ydb/mvp/oidc_proxy/mvp.cpp +++ b/ydb/mvp/oidc_proxy/mvp.cpp @@ -28,8 +28,7 @@ NActors::IActor* CreateMemProfiler(); -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { namespace { @@ -418,5 +417,4 @@ THolder TMVP::BuildActorSystemSetup(int argc, char** TAtomic TMVP::Quit = false; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/mvp.h b/ydb/mvp/oidc_proxy/mvp.h index 6e9294cac9ea..57508de5e8d3 100644 --- a/ydb/mvp/oidc_proxy/mvp.h +++ b/ydb/mvp/oidc_proxy/mvp.h @@ -12,8 +12,7 @@ #include #include "oidc_settings.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { const TString& GetEServiceName(NActors::NLog::EComponent component); @@ -72,5 +71,4 @@ class TMVP { int Shutdown(); }; -} // namespace NOIDC -} // namespace NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_client.cpp b/ydb/mvp/oidc_proxy/oidc_client.cpp index 825e1e71259d..5da68afe01d9 100644 --- a/ydb/mvp/oidc_proxy/oidc_client.cpp +++ b/ydb/mvp/oidc_proxy/oidc_client.cpp @@ -4,8 +4,9 @@ #include "oidc_impersonate_start_page_nebius.h" #include "oidc_impersonate_stop_page_nebius.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; void InitOIDC(NActors::TActorSystem& actorSystem, const NActors::TActorId& httpProxyId, @@ -37,5 +38,4 @@ void InitOIDC(NActors::TActorSystem& actorSystem, ); } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_client.h b/ydb/mvp/oidc_proxy/oidc_client.h index 47961f548ff8..884739632dfd 100644 --- a/ydb/mvp/oidc_proxy/oidc_client.h +++ b/ydb/mvp/oidc_proxy/oidc_client.h @@ -5,12 +5,10 @@ class TActorSystem; struct TActorId; } // NActors -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { struct TOpenIdConnectSettings; void InitOIDC(NActors::TActorSystem& actorSystem, const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp index 54880d0cf468..9c35ab9db539 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -7,13 +8,12 @@ #include "oidc_session_create.h" #include "oidc_impersonate_start_page_nebius.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { THandlerImpersonateStart::THandlerImpersonateStart(const NActors::TActorId& sender, - const NHttp::THttpIncomingRequestPtr& request, - const NActors::TActorId& httpProxyId, - const TOpenIdConnectSettings& settings) + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings) : Sender(sender) , Request(request) , HttpProxyId(httpProxyId) @@ -21,7 +21,8 @@ THandlerImpersonateStart::THandlerImpersonateStart(const NActors::TActorId& send {} void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "Start impersonation process"); + BLOG_D("Start impersonation process"); + NHttp::TUrlParameters urlParameters(Request->URL); TString serviceAccountId = urlParameters["service_account_id"]; @@ -31,32 +32,26 @@ void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { TString sessionCookieName = CreateNameSessionCookie(Settings.ClientId); TStringBuf sessionCookieValue = cookies.Get(sessionCookieName); if (!sessionCookieValue.Empty()) { - LOG_DEBUG_S(ctx, EService::MVP, "Using session cookie (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); + BLOG_D("Using session cookie (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); } + TString sessionToken = DecodeToken(sessionCookieValue); + TStringBuf impersonatedCookieValue = GetCookie(cookies, CreateNameImpersonatedCookie(Settings.ClientId)); - TString sessionToken = DecodeToken(sessionCookieValue, ctx); - - TString jsonError; if (sessionToken.empty()) { - jsonError = "Wrong impersonate parameter: session cookie not found"; - } else if (serviceAccountId.empty()) { - jsonError = "Wrong impersonate parameter: account_id not found"; + return ReplyBadRequestAndDie("Wrong impersonate parameter: session cookie not found", ctx); } - - if (jsonError) { - NHttp::THeadersBuilder responseHeaders; - responseHeaders.Set("Content-Type", "text/plain"); - SetCORS(Request, &responseHeaders); - NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, jsonError); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); - } else { - RequestImpersonatedToken(sessionToken, serviceAccountId, ctx); + if (!impersonatedCookieValue.empty()) { + return ReplyBadRequestAndDie("Wrong impersonate parameter: impersonated cookie already exists", ctx); } + if (serviceAccountId.empty()) { + return ReplyBadRequestAndDie("Wrong impersonate parameter: service_account_id not found", ctx); + } + + RequestImpersonatedToken(sessionToken, serviceAccountId, ctx); } void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionToken, const TString& serviceAccountId, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "Request impersonated token"); + BLOG_D("Request impersonated token"); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetImpersonateEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -70,7 +65,9 @@ void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionTo TStringBuilder body; body << "session=" << sessionToken << "&service_account_id=" << serviceAccountId; - httpRequest->Set<&NHttp::THttpRequest::Body>(body); + TString bodyStr = body; + CGIEscape(bodyStr); + httpRequest->Set<&NHttp::THttpRequest::Body>(bodyStr); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerImpersonateStart::StateWork); @@ -79,24 +76,22 @@ void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionTo void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersonatedToken, const NActors::TActorContext& ctx) { TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); TString impersonatedCookieValue = Base64Encode(impersonatedToken); - LOG_DEBUG_S(ctx, EService::MVP, "Set impersonated cookie: (" << impersonatedCookieName << ": " << NKikimr::MaskTicket(impersonatedCookieValue) << ")"); + BLOG_D("Set impersonated cookie: (" << impersonatedCookieName << ": " << NKikimr::MaskTicket(impersonatedCookieValue) << ")"); NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Set-Cookie", CreateSecureCookie(impersonatedCookieName, impersonatedCookieValue)); SetCORS(Request, &responseHeaders); - NHttp::THttpOutgoingResponsePtr httpResponse; - httpResponse = Request->CreateResponse("200", "OK", responseHeaders); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); + NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("200", "OK", responseHeaders); + ReplyAndDie(httpResponse, ctx); } void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Error.empty() && event->Get()->Response) { NHttp::THttpIncomingResponsePtr response = event->Get()->Response; - LOG_DEBUG_S(ctx, EService::MVP, "Incoming response from authorization server: " << response->Status); + BLOG_D("Incoming response from authorization server: " << response->Status); if (response->Status == "200") { - TStringBuf jsonError; + TStringBuf errorMessage; NJson::TJsonValue jsonValue; NJson::TJsonReaderConfig jsonConfig; if (NJson::ReadJsonTree(response->Body, &jsonConfig, &jsonValue)) { @@ -106,15 +101,15 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon ProcessImpersonatedToken(impersonatedToken, ctx); return; } else { - jsonError = "Wrong OIDC provider response: impersonated token not found"; + errorMessage = "Wrong OIDC provider response: impersonated token not found"; } } else { - jsonError = "Wrong OIDC response"; + errorMessage = "Wrong OIDC response"; } NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); - httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, jsonError); + return ReplyAndDie(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage), ctx); } else { NHttp::THeadersBuilder responseHeaders; NHttp::THeaders headers(response->Headers); @@ -122,18 +117,29 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon responseHeaders.Set("Content-Type", headers.Get("Content-Type")); } SetCORS(Request, &responseHeaders); - httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); + return ReplyAndDie(Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body), ctx); } } else { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); - httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); + return ReplyAndDie(Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error), ctx); } +} + +void THandlerImpersonateStart::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); Die(ctx); } +void THandlerImpersonateStart::ReplyBadRequestAndDie(const TString& errorMessage, const NActors::TActorContext& ctx) { + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Set("Content-Type", "text/plain"); + SetCORS(Request, &responseHeaders); + NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage); + ReplyAndDie(httpResponse, ctx); +} + TImpersonateStartPageHandler::TImpersonateStartPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) : TBase(&TImpersonateStartPageHandler::StateWork) , HttpProxyId(httpProxyId) @@ -144,5 +150,4 @@ void TImpersonateStartPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRe ctx.Register(new THandlerImpersonateStart(event->Sender, event->Get()->Request, HttpProxyId, Settings)); } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h index 37a332a7689f..40c8dcf0b541 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h @@ -3,8 +3,9 @@ #include "oidc_settings.h" #include "context.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class THandlerImpersonateStart : public NActors::TActorBootstrapped { private: @@ -13,7 +14,7 @@ class THandlerImpersonateStart : public NActors::TActorBootstrappedGetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; @@ -47,9 +50,9 @@ class TImpersonateStartPageHandler : public NActors::TActorGetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp index 3fa532a4fabf..30e7a6494ad7 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp @@ -1,14 +1,14 @@ #include "openid_connect.h" #include "oidc_session_create.h" #include "oidc_impersonate_stop_page_nebius.h" +#include -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { THandlerImpersonateStop::THandlerImpersonateStop(const NActors::TActorId& sender, - const NHttp::THttpIncomingRequestPtr& request, - const NActors::TActorId& httpProxyId, - const TOpenIdConnectSettings& settings) + const NHttp::THttpIncomingRequestPtr& request, + const NActors::TActorId& httpProxyId, + const TOpenIdConnectSettings& settings) : Sender(sender) , Request(request) , HttpProxyId(httpProxyId) @@ -17,7 +17,7 @@ THandlerImpersonateStop::THandlerImpersonateStop(const NActors::TActorId& sender void THandlerImpersonateStop::Bootstrap(const NActors::TActorContext& ctx) { TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); - LOG_DEBUG_S(ctx, EService::MVP, "Clear impersonated cookie: (" << impersonatedCookieName << ")"); + BLOG_D("Clear impersonated cookie: (" << impersonatedCookieName << ")"); NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Set-Cookie", ClearSecureCookie(impersonatedCookieName)); @@ -25,6 +25,10 @@ void THandlerImpersonateStop::Bootstrap(const NActors::TActorContext& ctx) { NHttp::THttpOutgoingResponsePtr httpResponse; httpResponse = Request->CreateResponse("200", "OK", responseHeaders); + ReplyAndDie(httpResponse, ctx); +} + +void THandlerImpersonateStop::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); Die(ctx); } @@ -39,5 +43,4 @@ void TImpersonateStopPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingReq ctx.Register(new THandlerImpersonateStop(event->Sender, event->Get()->Request, HttpProxyId, Settings)); } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h index 71f9d30fb6a4..6dd3c6e1fcd3 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h @@ -3,8 +3,9 @@ #include "oidc_settings.h" #include "context.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class THandlerImpersonateStop : public NActors::TActorBootstrapped { private: @@ -23,6 +24,7 @@ class THandlerImpersonateStop : public NActors::TActorBootstrapped { @@ -38,9 +40,9 @@ class TImpersonateStopPageHandler : public NActors::TActorGetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp index 52d7e6fbacd6..1c9a0aea0f9e 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp @@ -5,8 +5,7 @@ #include "openid_connect.h" #include "oidc_protected_page.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { THandlerSessionServiceCheck::THandlerSessionServiceCheck(const NActors::TActorId& sender, const NHttp::THttpIncomingRequestPtr& request, @@ -21,9 +20,7 @@ THandlerSessionServiceCheck::THandlerSessionServiceCheck(const NActors::TActorId void THandlerSessionServiceCheck::Bootstrap(const NActors::TActorContext& ctx) { if (!CheckRequestedHost()) { - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(CreateResponseForbiddenHost())); - Die(ctx); - return; + return ReplyAndDie(CreateResponseForbiddenHost(), ctx); } NHttp::THeaders headers(Request->Headers); TStringBuf authHeader = headers.Get(AUTH_HEADER_NAME); @@ -35,29 +32,25 @@ void THandlerSessionServiceCheck::Bootstrap(const NActors::TActorContext& ctx) { } void THandlerSessionServiceCheck::HandleProxy(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { - NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Response != nullptr) { NHttp::THttpIncomingResponsePtr response = event->Get()->Response; - LOG_DEBUG_S(ctx, EService::MVP, "Incoming response for protected resource: " << response->Status); + BLOG_D("Incoming response for protected resource: " << response->Status); if (NeedSendSecureHttpRequest(response)) { - SendSecureHttpRequest(response, ctx); - return; + return SendSecureHttpRequest(response, ctx); } NHttp::THeadersBuilder headers = GetResponseHeaders(response); TStringBuf contentType = headers.Get("Content-Type").NextTok(';'); if (contentType == "text/html") { TString newBody = FixReferenceInHtml(response->Body, response->GetRequest()->Host); - httpResponse = Request->CreateResponse( response->Status, response->Message, headers, newBody); + return ReplyAndDie(Request->CreateResponse(response->Status, response->Message, headers, newBody), ctx); } else { - httpResponse = Request->CreateResponse( response->Status, response->Message, headers, response->Body); + return ReplyAndDie(Request->CreateResponse(response->Status, response->Message, headers, response->Body), ctx); } } else { static constexpr size_t MAX_LOGGED_SIZE = 1024; - LOG_DEBUG_S(ctx, EService::MVP, "Can not process request to protected resource:\n" << event->Get()->Request->GetObfuscatedData().substr(0, MAX_LOGGED_SIZE)); - httpResponse = CreateResponseForNotExistingResponseFromProtectedResource(event->Get()->GetError()); + BLOG_D("Can not process request to protected resource:\n" << event->Get()->Request->GetObfuscatedData().substr(0, MAX_LOGGED_SIZE)); + return ReplyAndDie(CreateResponseForNotExistingResponseFromProtectedResource(event->Get()->GetError()), ctx); } - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); } bool THandlerSessionServiceCheck::CheckRequestedHost() { @@ -87,7 +80,7 @@ bool THandlerSessionServiceCheck::IsAuthorizedRequest(TStringBuf authHeader) { } void THandlerSessionServiceCheck::ForwardUserRequest(TStringBuf authHeader, const NActors::TActorContext& ctx, bool secure) { - LOG_DEBUG_S(ctx, EService::MVP, "Forward user request bypass OIDC"); + BLOG_D("Forward user request bypass OIDC"); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequest(Request->Method, ProtectedPageUrl); ForwardRequestHeaders(httpRequest); if (!authHeader.empty()) { @@ -182,7 +175,7 @@ NHttp::THeadersBuilder THandlerSessionServiceCheck::GetResponseHeaders(const NHt void THandlerSessionServiceCheck::SendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response, const NActors::TActorContext& ctx) { NHttp::THttpOutgoingRequestPtr request = response->GetRequest(); - LOG_DEBUG_S(ctx, EService::MVP, "Try to send request to HTTPS port"); + BLOG_D("Try to send request to HTTPS port"); NHttp::THeadersBuilder headers {request->Headers}; ForwardUserRequest(headers.Get(AUTH_HEADER_NAME), ctx, true); } @@ -233,5 +226,9 @@ NHttp::THttpOutgoingResponsePtr THandlerSessionServiceCheck::CreateResponseForNo return Request->CreateResponse("400", "Bad Request", headers, html); } -} // NOIDC -} // NMVP +void THandlerSessionServiceCheck::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Die(ctx); +} + +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page.h b/ydb/mvp/oidc_proxy/oidc_protected_page.h index 9bf7b4fce9a5..f8e13fe824a0 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page.h @@ -8,8 +8,7 @@ #include #include "oidc_settings.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { class THandlerSessionServiceCheck : public NActors::TActorBootstrapped { protected: @@ -17,9 +16,9 @@ class THandlerSessionServiceCheck : public NActors::TActorBootstrapped #include "oidc_settings.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class TProtectedPageHandler : public NActors::TActor { using TBase = NActors::TActor; @@ -21,9 +22,9 @@ class TProtectedPageHandler : public NActors::TActor { STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp index 0b84a1af1bc9..121bf1179ce2 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp @@ -1,15 +1,15 @@ #include #include +#include #include -#include #include #include #include #include "openid_connect.h" #include "context.h" #include "oidc_protected_page_nebius.h" -namespace NMVP { -namespace NOIDC { + +namespace NMVP::NOIDC { THandlerSessionServiceCheckNebius::THandlerSessionServiceCheckNebius(const NActors::TActorId& sender, const NHttp::THttpIncomingRequestPtr& request, @@ -18,25 +18,17 @@ THandlerSessionServiceCheckNebius::THandlerSessionServiceCheckNebius(const NActo : THandlerSessionServiceCheck(sender, request, httpProxyId, settings) {} -TStringBuf THandlerSessionServiceCheckNebius::GetCookie(const NHttp::TCookies& cookies, const TString& cookieName, const NActors::TActorContext& ctx) { - TStringBuf cookieValue = cookies.Get(cookieName); - if (!cookieValue.Empty()) { - LOG_DEBUG_S(ctx, EService::MVP, "Using cookie (" << cookieName << ": " << NKikimr::MaskTicket(cookieValue) << ")"); - } - return cookieValue; -} - void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorContext& ctx) { NHttp::THeaders headers(Request->Headers); - LOG_DEBUG_S(ctx, EService::MVP, "Start OIDC process"); + BLOG_D("Start OIDC process"); NHttp::TCookies cookies(headers.Get("Cookie")); - TStringBuf sessionCookieValue = GetCookie(cookies, CreateNameSessionCookie(Settings.ClientId), ctx); - TStringBuf impersonatedCookieValue = GetCookie(cookies, CreateNameImpersonatedCookie(Settings.ClientId), ctx); + TStringBuf sessionCookieValue = GetCookie(cookies, CreateNameSessionCookie(Settings.ClientId)); + TStringBuf impersonatedCookieValue = GetCookie(cookies, CreateNameImpersonatedCookie(Settings.ClientId)); - TString sessionToken = DecodeToken(sessionCookieValue, ctx); + TString sessionToken = DecodeToken(sessionCookieValue); if (sessionToken) { - TString impersonatedToken = DecodeToken(impersonatedCookieValue, ctx); + TString impersonatedToken = DecodeToken(impersonatedCookieValue); if (impersonatedToken) { ExchangeImpersonatedToken(sessionToken, impersonatedToken, ctx); } else { @@ -49,43 +41,39 @@ void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorCo void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { if (!event->Get()->Response) { - LOG_DEBUG_S(ctx, EService::MVP, "Getting access token: Bad Request"); + BLOG_D("Getting access token: Bad Request"); NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); - } else { - NHttp::THttpIncomingResponsePtr response = event->Get()->Response; - LOG_DEBUG_S(ctx, EService::MVP, "Getting access token: " << response->Status << " " << response->Message); - if (response->Status == "200") { - TString iamToken; - static const NJson::TJsonReaderConfig JsonConfig; - NJson::TJsonValue requestData; - bool success = NJson::ReadJsonTree(response->Body, &JsonConfig, &requestData); - if (success) { - iamToken = requestData["access_token"].GetStringSafe({}); - const TString authHeader = IAM_TOKEN_SCHEME + iamToken; - ForwardUserRequest(authHeader, ctx); - return; - } - } else if (response->Status == "400" || response->Status == "401") { - LOG_DEBUG_S(ctx, EService::MVP, "Getting access token: " << response->Body); - if (tokenExchangeType == ETokenExchangeType::ImpersonatedToken) { - ClearImpersonatedCookie(ctx); - } else { - RequestAuthorizationCode(ctx); - } - return; + return ReplyAndDie(httpResponse, ctx); + } + + NHttp::THttpIncomingResponsePtr response = event->Get()->Response; + BLOG_D("Getting access token: " << response->Status << " " << response->Message); + if (response->Status == "200") { + TString iamToken; + static const NJson::TJsonReaderConfig JsonConfig; + NJson::TJsonValue requestData; + bool success = NJson::ReadJsonTree(response->Body, &JsonConfig, &requestData); + if (success) { + iamToken = requestData["access_token"].GetStringSafe({}); + const TString authHeader = IAM_TOKEN_SCHEME + iamToken; + return ForwardUserRequest(authHeader, ctx); + } + } else if (response->Status == "400" || response->Status == "401") { + BLOG_D("Getting access token: " << response->Body); + if (tokenExchangeType == ETokenExchangeType::ImpersonatedToken) { + return ClearImpersonatedCookie(ctx); + } else { + return RequestAuthorizationCode(ctx); } - // don't know what to do, just forward response - NHttp::THttpOutgoingResponsePtr httpResponse; - NHttp::THeadersBuilder responseHeaders; - responseHeaders.Parse(response->Headers); - httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); } + // don't know what to do, just forward response + NHttp::THttpOutgoingResponsePtr httpResponse; + NHttp::THeadersBuilder responseHeaders; + responseHeaders.Parse(response->Headers); + httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); + ReplyAndDie(httpResponse, ctx); } void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx) { @@ -99,14 +87,17 @@ void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBu token = tokenator->GetToken(Settings.SessionServiceTokenName); } httpRequest->Set("Authorization", token); // Bearer included - httpRequest->Set<&NHttp::THttpRequest::Body>(body); + + TString bodyStr = body; + CGIEscape(bodyStr); + httpRequest->Set<&NHttp::THttpRequest::Body>(bodyStr); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionServiceCheckNebius::StateExchange); } -void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessionToken, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "Exchange session token"); +void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) { + BLOG_D("Exchange session token"); TStringBuilder body; body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" @@ -116,8 +107,8 @@ void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessi SendTokenExchangeRequest(body, ETokenExchangeType::SessionToken, ctx); } -void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString sessionToken, const TString impersonatedToken, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "Exchange impersonated token"); +void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString& sessionToken, const TString& impersonatedToken, const NActors::TActorContext& ctx) { + BLOG_D("Exchange impersonated token"); TStringBuilder body; body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" @@ -131,20 +122,20 @@ void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie(const NActors::TActorContext& ctx) { TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); - LOG_DEBUG_S(ctx, EService::MVP, "Clear impersonated cookie (" << impersonatedCookieName << ") and retry"); + BLOG_D("Clear impersonated cookie (" << impersonatedCookieName << ") and retry"); NHttp::THeadersBuilder responseHeaders; SetCORS(Request, &responseHeaders); responseHeaders.Set("Set-Cookie", ClearSecureCookie(impersonatedCookieName)); responseHeaders.Set("Location", Request->URL); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("307", "Temporary Redirect", responseHeaders))); - Die(ctx); + + NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("307", "Temporary Redirect", responseHeaders); + ReplyAndDie(httpResponse, ctx); } void THandlerSessionServiceCheckNebius::RequestAuthorizationCode(const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "Request authorization code"); + BLOG_D("Request authorization code"); NHttp::THttpOutgoingResponsePtr httpResponse = GetHttpOutgoingResponsePtr(Request, Settings); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); + ReplyAndDie(httpResponse, ctx); } void THandlerSessionServiceCheckNebius::ForwardUserRequest(TStringBuf authHeader, const NActors::TActorContext& ctx, bool secure) { @@ -159,5 +150,4 @@ bool THandlerSessionServiceCheckNebius::NeedSendSecureHttpRequest(const NHttp::T return false; } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h index d80cc29474e8..8909607885e0 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h @@ -2,8 +2,9 @@ #include "oidc_protected_page.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { private: @@ -22,31 +23,31 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { const NHttp::THttpIncomingRequestPtr& request, const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - TStringBuf GetCookie(const NHttp::TCookies& cookies, const TString& cookieName, const NActors::TActorContext& ctx); void StartOidcProcess(const NActors::TActorContext& ctx) override; void HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx); STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } STFUNC(StateExchange) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleExchange); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } private: void SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx); - void ExchangeSessionToken(const TString sessionToken, const NActors::TActorContext& ctx); - void ExchangeImpersonatedToken(const TString sessionToken, const TString impersonatedToken, const NActors::TActorContext& ctx); + void ExchangeSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx); + void ExchangeImpersonatedToken(const TString& sessionToken, const TString& impersonatedToken, const NActors::TActorContext& ctx); void ClearImpersonatedCookie(const NActors::TActorContext& ctx); void RequestAuthorizationCode(const NActors::TActorContext& ctx); void ForwardUserRequest(TStringBuf authHeader, const NActors::TActorContext& ctx, bool secure = false) override; bool NeedSendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response) const override; }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp index 041fe927cf9b..e8b50d2bb273 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp @@ -22,7 +22,7 @@ void THandlerSessionServiceCheckYandex::Bootstrap(const NActors::TActorContext& } void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvCheckSessionResponse::TPtr event, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "SessionService.Check(): OK"); + BLOG_D("SessionService.Check(): OK"); auto response = event->Get()->Response; const auto& iamToken = response.iam_token(); const TString authHeader = IAM_TOKEN_SCHEME + iamToken.iam_token(); @@ -30,15 +30,13 @@ void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvCheckSessionRespon } void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvErrorResponse::TPtr event, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "SessionService.Check(): " << event->Get()->Status); + BLOG_D("SessionService.Check(): " << event->Get()->Status); NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Status == "400") { - httpResponse = GetHttpOutgoingResponsePtr(Request, Settings); + return ReplyAndDie(GetHttpOutgoingResponsePtr(Request, Settings), ctx); } else { - httpResponse = Request->CreateResponse( event->Get()->Status, event->Get()->Message, "text/plain", event->Get()->Details); + return ReplyAndDie(Request->CreateResponse( event->Get()->Status, event->Get()->Message, "text/plain", event->Get()->Details), ctx); } - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); } void THandlerSessionServiceCheckYandex::StartOidcProcess(const NActors::TActorContext& ctx) { diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h index 9f4f2f5f8ed4..d0233d48274b 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h @@ -3,8 +3,9 @@ #include "openid_connect.h" #include "oidc_protected_page.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class THandlerSessionServiceCheckYandex : public THandlerSessionServiceCheck { private: @@ -27,6 +28,7 @@ class THandlerSessionServiceCheckYandex : public THandlerSessionServiceCheck { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); HFunc(TEvPrivate::TEvCheckSessionResponse, Handle); HFunc(TEvPrivate::TEvErrorResponse, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } @@ -35,5 +37,4 @@ class THandlerSessionServiceCheckYandex : public THandlerSessionServiceCheck { bool NeedSendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response) const override; }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp b/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp index 53c27dd80358..63a9d79d8979 100644 --- a/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp +++ b/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp @@ -641,8 +641,8 @@ Y_UNIT_TEST_SUITE(Mvp) { auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); + UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); const TString authorizationServerResponse = R"___({"access_token":"access_token_value","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); @@ -793,8 +793,8 @@ Y_UNIT_TEST_SUITE(Mvp) { TAutoPtr handle; auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); + UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); const TString authorizationServerResponse = R"___({"access_token":"access_token_value","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); @@ -848,8 +848,8 @@ Y_UNIT_TEST_SUITE(Mvp) { TAutoPtr handle; auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); + UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); const TString authorizationServerResponse = R"___({"access_token":"invalid_access_token","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); @@ -914,8 +914,9 @@ Y_UNIT_TEST_SUITE(Mvp) { TAutoPtr handle; auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); + + UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); const TString authorizationServerResponse = R"___({"access_token":"access_token_value","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.cpp b/ydb/mvp/oidc_proxy/oidc_session_create.cpp index 9f5670538579..1b2129415c42 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create.cpp @@ -6,8 +6,7 @@ #include "oidc_session_create.h" #include "oidc_settings.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { THandlerSessionCreate::THandlerSessionCreate(const NActors::TActorId& sender, const NHttp::THttpIncomingRequestPtr& request, @@ -64,9 +63,9 @@ void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse: NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Error.empty() && event->Get()->Response) { NHttp::THttpIncomingResponsePtr response = event->Get()->Response; - LOG_DEBUG_S(ctx, EService::MVP, "Incoming response from authorization server: " << response->Status); + BLOG_D("Incoming response from authorization server: " << response->Status); if (response->Status == "200") { - TStringBuf jsonError; + TStringBuf errorMessage; NJson::TJsonValue jsonValue; NJson::TJsonReaderConfig jsonConfig; if (NJson::ReadJsonTree(response->Body, &jsonConfig, &jsonValue)) { @@ -76,14 +75,14 @@ void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse: ProcessSessionToken(sessionToken, ctx); return; } else { - jsonError = "Wrong OIDC provider response: access_token not found"; + errorMessage = "Wrong OIDC provider response: access_token not found"; } } else { - jsonError = "Wrong OIDC response"; + errorMessage = "Wrong OIDC response"; } NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); - httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, jsonError); + httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage); } else { NHttp::THeadersBuilder responseHeaders; responseHeaders.Parse(response->Headers); @@ -94,8 +93,7 @@ void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse: responseHeaders.Set("Content-Type", "text/plain"); httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); } - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); + ReplyAndDie(httpResponse, ctx); } TString THandlerSessionCreate::ChangeSameSiteFieldInSessionCookie(const TString& cookie) { @@ -119,8 +117,7 @@ void THandlerSessionCreate::RetryRequestToProtectedResourceAndDie(const NActors: void THandlerSessionCreate::RetryRequestToProtectedResourceAndDie(NHttp::THeadersBuilder* responseHeaders, const NActors::TActorContext& ctx) { SetCORS(Request, responseHeaders); responseHeaders->Set("Location", Context.GetRequestedAddress()); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("302", "Found", *responseHeaders))); - Die(ctx); + ReplyAndDie(Request->CreateResponse("302", "Found", *responseHeaders), ctx); } void THandlerSessionCreate::SendUnknownErrorResponseAndDie(const NActors::TActorContext& ctx) { @@ -141,9 +138,12 @@ void THandlerSessionCreate::SendUnknownErrorResponseAndDie(const NActors::TActor "" "" ""; - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request->CreateResponse("400", "Bad Request", responseHeaders, BAD_REQUEST_HTML_PAGE))); + ReplyAndDie(Request->CreateResponse("400", "Bad Request", responseHeaders, BAD_REQUEST_HTML_PAGE), ctx); +} + +void THandlerSessionCreate::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { + ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); Die(ctx); } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.h b/ydb/mvp/oidc_proxy/oidc_session_create.h index b8ef1c183e7a..c0a5045ef1ce 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create.h @@ -9,8 +9,7 @@ #include "oidc_settings.h" #include "context.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { class THandlerSessionCreate : public NActors::TActorBootstrapped { private: @@ -19,7 +18,7 @@ class THandlerSessionCreate : public NActors::TActorBootstrappedSender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response)); } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_handler.h b/ydb/mvp/oidc_proxy/oidc_session_create_handler.h index 232968656583..b8225f4bd7aa 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_handler.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_handler.h @@ -5,8 +5,9 @@ #include #include "oidc_settings.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class TSessionCreateHandler : public NActors::TActor { using TBase = NActors::TActor; @@ -21,9 +22,9 @@ class TSessionCreateHandler : public NActors::TActor { STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp index 964a602baacf..36c9bda01e92 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp @@ -3,9 +3,9 @@ #include "openid_connect.h" #include "oidc_session_create_nebius.h" #include +#include -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { THandlerSessionCreateNebius::THandlerSessionCreateNebius(const NActors::TActorId& sender, const NHttp::THttpIncomingRequestPtr& request, @@ -28,7 +28,10 @@ void THandlerSessionCreateNebius::RequestSessionToken(const TString& code, const NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetTokenEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); httpRequest->Set("Authorization", Settings.GetAuthorizationString()); - httpRequest->Set<&NHttp::THttpRequest::Body>(body); + + TString bodyStr = body; + CGIEscape(bodyStr); + httpRequest->Set<&NHttp::THttpRequest::Body>(bodyStr); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionCreateNebius::StateWork); @@ -37,16 +40,14 @@ void THandlerSessionCreateNebius::RequestSessionToken(const TString& code, const void THandlerSessionCreateNebius::ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) { TString sessionCookieName = CreateNameSessionCookie(Settings.ClientId); TString sessionCookieValue = Base64Encode(sessionToken); - LOG_DEBUG_S(ctx, EService::MVP, "Set session cookie: (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); + BLOG_D("Set session cookie: (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Set-Cookie", CreateSecureCookie(sessionCookieName, sessionCookieValue)); responseHeaders.Set("Location", Context.GetRequestedAddress()); NHttp::THttpOutgoingResponsePtr httpResponse; httpResponse = Request->CreateResponse("302", "Cookie set", responseHeaders); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); + ReplyAndDie(httpResponse, ctx); } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h index cbe8ca386017..38202f290f42 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h @@ -2,8 +2,9 @@ #include "oidc_session_create.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class THandlerSessionCreateNebius : public THandlerSessionCreate { private: @@ -22,9 +23,9 @@ class THandlerSessionCreateNebius : public THandlerSessionCreate { STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp index 8a6291209b2a..28a3b3be0a1b 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "oidc_session_create_yandex.h" namespace NMVP { @@ -20,8 +21,8 @@ void THandlerSessionCreateYandex::RequestSessionToken(const TString& code, const NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetTokenEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); httpRequest->Set("Authorization", Settings.GetAuthorizationString()); - TStringBuilder body; - body << "grant_type=authorization_code&code=" << code; + TString body = "grant_type=authorization_code&code=" + code; + CGIEscape(body); httpRequest->Set<&NHttp::THttpRequest::Body>(body); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionCreateYandex::StateWork); @@ -56,7 +57,7 @@ void THandlerSessionCreateYandex::ProcessSessionToken(const TString& sessionToke } void THandlerSessionCreateYandex::HandleCreateSession(TEvPrivate::TEvCreateSessionResponse::TPtr event, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "SessionService.Create(): OK"); + BLOG_D("SessionService.Create(): OK"); auto response = event->Get()->Response; NHttp::THeadersBuilder responseHeaders; for (const auto& cookie : response.Getset_cookie_header()) { @@ -66,7 +67,7 @@ void THandlerSessionCreateYandex::HandleCreateSession(TEvPrivate::TEvCreateSessi } void THandlerSessionCreateYandex::HandleError(TEvPrivate::TEvErrorResponse::TPtr event, const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, EService::MVP, "SessionService.Create(): " << event->Get()->Status); + BLOG_D("SessionService.Create(): " << event->Get()->Status); if (event->Get()->Status == "400") { RetryRequestToProtectedResourceAndDie(ctx); } else { @@ -74,12 +75,11 @@ void THandlerSessionCreateYandex::HandleError(TEvPrivate::TEvErrorResponse::TPtr responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse( event->Get()->Status, event->Get()->Message, responseHeaders, event->Get()->Details); - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); + ReplyAndDie(httpResponse, ctx); } } -} // NOIDC +} // NMVP template<> TString SecureShortDebugString(const yandex::cloud::priv::oauth::v1::CreateSessionRequest& request) { diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h index 961fdfb79ca1..26efa7792f74 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h @@ -3,8 +3,9 @@ #include "oidc_session_create.h" #include "openid_connect.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { + +using namespace NActors; class THandlerSessionCreateYandex : public THandlerSessionCreate { private: @@ -28,9 +29,9 @@ class THandlerSessionCreateYandex : public THandlerSessionCreate { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); HFunc(TEvPrivate::TEvCreateSessionResponse, HandleCreateSession); HFunc(TEvPrivate::TEvErrorResponse, HandleError); + cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_settings.cpp b/ydb/mvp/oidc_proxy/oidc_settings.cpp index 81c8645d36ce..ec02e593b038 100644 --- a/ydb/mvp/oidc_proxy/oidc_settings.cpp +++ b/ydb/mvp/oidc_proxy/oidc_settings.cpp @@ -2,8 +2,7 @@ #include #include "oidc_settings.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { TString TOpenIdConnectSettings::GetAuthorizationString() const { return "Basic " + Base64Encode(ClientId + ":" + ClientSecret); @@ -25,5 +24,4 @@ TString TOpenIdConnectSettings::GetImpersonateEndpointURL() const { return AuthorizationServerAddress + ImpersonateUrlPath; } -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_settings.h b/ydb/mvp/oidc_proxy/oidc_settings.h index 878f3d1ba68c..47925ddb803c 100644 --- a/ydb/mvp/oidc_proxy/oidc_settings.h +++ b/ydb/mvp/oidc_proxy/oidc_settings.h @@ -3,8 +3,7 @@ #include #include -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { struct TOpenIdConnectSettings { static const inline TString YDB_OIDC_COOKIE = "ydb_oidc_cookie"; @@ -37,5 +36,4 @@ struct TOpenIdConnectSettings { TString GetImpersonateEndpointURL() const; }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/openid_connect.cpp b/ydb/mvp/oidc_proxy/openid_connect.cpp index de68c3113ca1..b108899f8682 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.cpp +++ b/ydb/mvp/oidc_proxy/openid_connect.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -10,8 +11,7 @@ #include "openid_connect.h" #include "oidc_settings.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { namespace { @@ -237,16 +237,23 @@ TCheckStateResult CheckState(const TString& state, const TString& key) { return TCheckStateResult(); } -TString DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx) { +TString DecodeToken(const TStringBuf& cookie) { TString token; try { Base64StrictDecode(cookie, token); } catch (std::exception& e) { - LOG_DEBUG_S(ctx, EService::MVP, "Base64Decode " << cookie << " cookie: " << e.what()); + BLOG_D("Base64Decode " << cookie << " cookie: " << e.what()); token.clear(); } return token; } -} // NOIDC -} // NMVP +TStringBuf GetCookie(const NHttp::TCookies& cookies, const TString& cookieName) { + TStringBuf cookieValue = cookies.Get(cookieName); + if (!cookieValue.Empty()) { + BLOG_D("Using cookie (" << cookieName << ": " << NKikimr::MaskTicket(cookieValue) << ")"); + } + return cookieValue; +} + +} // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/openid_connect.h b/ydb/mvp/oidc_proxy/openid_connect.h index 3706417b0c2b..3c3e8171be22 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.h +++ b/ydb/mvp/oidc_proxy/openid_connect.h @@ -9,8 +9,7 @@ #include #include "context.h" -namespace NMVP { -namespace NOIDC { +namespace NMVP::NOIDC { struct TOpenIdConnectSettings; @@ -51,7 +50,8 @@ TString ClearSecureCookie(const TString& name); void SetCORS(const NHttp::THttpIncomingRequestPtr& request, NHttp::THeadersBuilder* const headers); TRestoreOidcContextResult RestoreOidcContext(const NHttp::TCookies& cookies, const TString& key); TCheckStateResult CheckState(const TString& state, const TString& key); -TString DecodeToken(const TStringBuf& cookie, const NActors::TActorContext& ctx); +TString DecodeToken(const TStringBuf& cookie); +TStringBuf GetCookie(const NHttp::TCookies& cookies, const TString& cookieName); template std::unique_ptr> CreateGRpcServiceConnection(const TString& endpoint) { @@ -145,5 +145,4 @@ struct TEvPrivate { }; }; -} // NOIDC -} // NMVP +} // NMVP::NOIDC From 18ba2920b3a9a1c9c0ba560db473c8a0fabdbf7f Mon Sep 17 00:00:00 2001 From: StekPerepolnen Date: Wed, 27 Nov 2024 01:13:40 +0000 Subject: [PATCH 5/7] escape only values --- .../oidc_impersonate_start_page_nebius.cpp | 38 +++++++-------- .../oidc_impersonate_start_page_nebius.h | 12 ++--- .../oidc_impersonate_stop_page_nebius.cpp | 10 ++-- .../oidc_impersonate_stop_page_nebius.h | 4 +- ydb/mvp/oidc_proxy/oidc_protected_page.cpp | 28 +++++------ ydb/mvp/oidc_proxy/oidc_protected_page.h | 8 ++-- .../oidc_proxy/oidc_protected_page_nebius.cpp | 38 +++++++-------- .../oidc_proxy/oidc_protected_page_nebius.h | 16 +++---- .../oidc_proxy/oidc_protected_page_yandex.cpp | 10 ++-- .../oidc_proxy/oidc_protected_page_yandex.h | 10 ++-- ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp | 46 +++++++++---------- ydb/mvp/oidc_proxy/oidc_session_create.cpp | 30 ++++++------ ydb/mvp/oidc_proxy/oidc_session_create.h | 10 ++-- .../oidc_proxy/oidc_session_create_nebius.cpp | 17 ++++--- .../oidc_proxy/oidc_session_create_nebius.h | 2 +- .../oidc_proxy/oidc_session_create_yandex.cpp | 20 ++++---- .../oidc_proxy/oidc_session_create_yandex.h | 10 ++-- ydb/mvp/oidc_proxy/oidc_settings.cpp | 4 +- ydb/mvp/oidc_proxy/oidc_settings.h | 2 +- ydb/mvp/oidc_proxy/openid_connect.cpp | 16 +++---- ydb/mvp/oidc_proxy/openid_connect.h | 8 ++-- 21 files changed, 171 insertions(+), 168 deletions(-) diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp index 9c35ab9db539..5c3de4b018e0 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp @@ -38,19 +38,19 @@ void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { TStringBuf impersonatedCookieValue = GetCookie(cookies, CreateNameImpersonatedCookie(Settings.ClientId)); if (sessionToken.empty()) { - return ReplyBadRequestAndDie("Wrong impersonate parameter: session cookie not found", ctx); + return ReplyBadRequestAndPassAway("Wrong impersonate parameter: session cookie not found"); } if (!impersonatedCookieValue.empty()) { - return ReplyBadRequestAndDie("Wrong impersonate parameter: impersonated cookie already exists", ctx); + return ReplyBadRequestAndPassAway("Wrong impersonate parameter: impersonated cookie already exists"); } if (serviceAccountId.empty()) { - return ReplyBadRequestAndDie("Wrong impersonate parameter: service_account_id not found", ctx); + return ReplyBadRequestAndPassAway("Wrong impersonate parameter: service_account_id not found"); } RequestImpersonatedToken(sessionToken, serviceAccountId, ctx); } -void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionToken, const TString& serviceAccountId, const NActors::TActorContext& ctx) { +void THandlerImpersonateStart::RequestImpersonatedToken(TString& sessionToken, TString& serviceAccountId, const NActors::TActorContext& ctx) { BLOG_D("Request impersonated token"); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetImpersonateEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -62,18 +62,18 @@ void THandlerImpersonateStart::RequestImpersonatedToken(const TString& sessionTo } httpRequest->Set("Authorization", token); // Bearer included + CGIEscape(sessionToken); + CGIEscape(serviceAccountId); TStringBuilder body; body << "session=" << sessionToken << "&service_account_id=" << serviceAccountId; - TString bodyStr = body; - CGIEscape(bodyStr); - httpRequest->Set<&NHttp::THttpRequest::Body>(bodyStr); + httpRequest->Set<&NHttp::THttpRequest::Body>(body); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerImpersonateStart::StateWork); } -void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersonatedToken, const NActors::TActorContext& ctx) { +void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersonatedToken) { TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); TString impersonatedCookieValue = Base64Encode(impersonatedToken); BLOG_D("Set impersonated cookie: (" << impersonatedCookieName << ": " << NKikimr::MaskTicket(impersonatedCookieValue) << ")"); @@ -82,10 +82,10 @@ void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersona responseHeaders.Set("Set-Cookie", CreateSecureCookie(impersonatedCookieName, impersonatedCookieValue)); SetCORS(Request, &responseHeaders); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("200", "OK", responseHeaders); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } -void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { +void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) { NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Error.empty() && event->Get()->Response) { NHttp::THttpIncomingResponsePtr response = event->Get()->Response; @@ -98,7 +98,7 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon const NJson::TJsonValue* jsonImpersonatedToken; if (jsonValue.GetValuePointer("impersonation", &jsonImpersonatedToken)) { TString impersonatedToken = jsonImpersonatedToken->GetStringRobust(); - ProcessImpersonatedToken(impersonatedToken, ctx); + ProcessImpersonatedToken(impersonatedToken); return; } else { errorMessage = "Wrong OIDC provider response: impersonated token not found"; @@ -109,7 +109,7 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); - return ReplyAndDie(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage), ctx); + return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage)); } else { NHttp::THeadersBuilder responseHeaders; NHttp::THeaders headers(response->Headers); @@ -117,27 +117,27 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon responseHeaders.Set("Content-Type", headers.Get("Content-Type")); } SetCORS(Request, &responseHeaders); - return ReplyAndDie(Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body), ctx); + return ReplyAndPassAway(Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body)); } } else { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); - return ReplyAndDie(Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error), ctx); + return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error)); } } -void THandlerImpersonateStart::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); +void THandlerImpersonateStart::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + PassAway(); } -void THandlerImpersonateStart::ReplyBadRequestAndDie(const TString& errorMessage, const NActors::TActorContext& ctx) { +void THandlerImpersonateStart::ReplyBadRequestAndPassAway(const TString& errorMessage) { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } TImpersonateStartPageHandler::TImpersonateStartPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h index 40c8dcf0b541..ed4ff9a831b7 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h @@ -23,15 +23,15 @@ class THandlerImpersonateStart : public NActors::TActorBootstrappedGetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp index 30e7a6494ad7..36305292d096 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp @@ -15,7 +15,7 @@ THandlerImpersonateStop::THandlerImpersonateStop(const NActors::TActorId& sender , Settings(settings) {} -void THandlerImpersonateStop::Bootstrap(const NActors::TActorContext& ctx) { +void THandlerImpersonateStop::Bootstrap() { TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); BLOG_D("Clear impersonated cookie: (" << impersonatedCookieName << ")"); @@ -25,12 +25,12 @@ void THandlerImpersonateStop::Bootstrap(const NActors::TActorContext& ctx) { NHttp::THttpOutgoingResponsePtr httpResponse; httpResponse = Request->CreateResponse("200", "OK", responseHeaders); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } -void THandlerImpersonateStop::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); +void THandlerImpersonateStop::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + PassAway(); } TImpersonateStopPageHandler::TImpersonateStopPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h index 6dd3c6e1fcd3..9f7fd296fbf9 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h @@ -23,8 +23,8 @@ class THandlerImpersonateStop : public NActors::TActorBootstrapped { diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp index 1c9a0aea0f9e..bbef5c002d16 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp @@ -20,36 +20,36 @@ THandlerSessionServiceCheck::THandlerSessionServiceCheck(const NActors::TActorId void THandlerSessionServiceCheck::Bootstrap(const NActors::TActorContext& ctx) { if (!CheckRequestedHost()) { - return ReplyAndDie(CreateResponseForbiddenHost(), ctx); + return ReplyAndPassAway(CreateResponseForbiddenHost()); } NHttp::THeaders headers(Request->Headers); TStringBuf authHeader = headers.Get(AUTH_HEADER_NAME); if (Request->Method == "OPTIONS" || IsAuthorizedRequest(authHeader)) { - ForwardUserRequest(TString(authHeader), ctx); + ForwardUserRequest(TString(authHeader)); } else { StartOidcProcess(ctx); } } -void THandlerSessionServiceCheck::HandleProxy(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheck::HandleProxy(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) { if (event->Get()->Response != nullptr) { NHttp::THttpIncomingResponsePtr response = event->Get()->Response; BLOG_D("Incoming response for protected resource: " << response->Status); if (NeedSendSecureHttpRequest(response)) { - return SendSecureHttpRequest(response, ctx); + return SendSecureHttpRequest(response); } NHttp::THeadersBuilder headers = GetResponseHeaders(response); TStringBuf contentType = headers.Get("Content-Type").NextTok(';'); if (contentType == "text/html") { TString newBody = FixReferenceInHtml(response->Body, response->GetRequest()->Host); - return ReplyAndDie(Request->CreateResponse(response->Status, response->Message, headers, newBody), ctx); + return ReplyAndPassAway(Request->CreateResponse(response->Status, response->Message, headers, newBody)); } else { - return ReplyAndDie(Request->CreateResponse(response->Status, response->Message, headers, response->Body), ctx); + return ReplyAndPassAway(Request->CreateResponse(response->Status, response->Message, headers, response->Body)); } } else { static constexpr size_t MAX_LOGGED_SIZE = 1024; BLOG_D("Can not process request to protected resource:\n" << event->Get()->Request->GetObfuscatedData().substr(0, MAX_LOGGED_SIZE)); - return ReplyAndDie(CreateResponseForNotExistingResponseFromProtectedResource(event->Get()->GetError()), ctx); + return ReplyAndPassAway(CreateResponseForNotExistingResponseFromProtectedResource(event->Get()->GetError())); } } @@ -79,7 +79,7 @@ bool THandlerSessionServiceCheck::IsAuthorizedRequest(TStringBuf authHeader) { return to_lower(ToString(authHeader)).StartsWith(IAM_TOKEN_SCHEME_LOWER); } -void THandlerSessionServiceCheck::ForwardUserRequest(TStringBuf authHeader, const NActors::TActorContext& ctx, bool secure) { +void THandlerSessionServiceCheck::ForwardUserRequest(TStringBuf authHeader, bool secure) { BLOG_D("Forward user request bypass OIDC"); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequest(Request->Method, ProtectedPageUrl); ForwardRequestHeaders(httpRequest); @@ -92,7 +92,7 @@ void THandlerSessionServiceCheck::ForwardUserRequest(TStringBuf authHeader, cons if (RequestedPageScheme.empty()) { httpRequest->Secure = secure; } - ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); } TString THandlerSessionServiceCheck::FixReferenceInHtml(TStringBuf html, TStringBuf host, TStringBuf findStr) { @@ -173,11 +173,11 @@ NHttp::THeadersBuilder THandlerSessionServiceCheck::GetResponseHeaders(const NHt return resultHeaders; } -void THandlerSessionServiceCheck::SendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheck::SendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response) { NHttp::THttpOutgoingRequestPtr request = response->GetRequest(); BLOG_D("Try to send request to HTTPS port"); NHttp::THeadersBuilder headers {request->Headers}; - ForwardUserRequest(headers.Get(AUTH_HEADER_NAME), ctx, true); + ForwardUserRequest(headers.Get(AUTH_HEADER_NAME), true); } TString THandlerSessionServiceCheck::GetFixedLocationHeader(TStringBuf location) { @@ -226,9 +226,9 @@ NHttp::THttpOutgoingResponsePtr THandlerSessionServiceCheck::CreateResponseForNo return Request->CreateResponse("400", "Bad Request", headers, html); } -void THandlerSessionServiceCheck::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); +void THandlerSessionServiceCheck::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + PassAway(); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page.h b/ydb/mvp/oidc_proxy/oidc_protected_page.h index f8e13fe824a0..6b18aa253689 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page.h @@ -32,16 +32,16 @@ class THandlerSessionServiceCheck : public NActors::TActorBootstrappedGet()->Response) { BLOG_D("Getting access token: Bad Request"); NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); - return ReplyAndDie(httpResponse, ctx); + return ReplyAndPassAway(httpResponse); } NHttp::THttpIncomingResponsePtr response = event->Get()->Response; @@ -58,14 +58,14 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv if (success) { iamToken = requestData["access_token"].GetStringSafe({}); const TString authHeader = IAM_TOKEN_SCHEME + iamToken; - return ForwardUserRequest(authHeader, ctx); + return ForwardUserRequest(authHeader); } } else if (response->Status == "400" || response->Status == "401") { BLOG_D("Getting access token: " << response->Body); if (tokenExchangeType == ETokenExchangeType::ImpersonatedToken) { - return ClearImpersonatedCookie(ctx); + return ClearImpersonatedCookie(); } else { - return RequestAuthorizationCode(ctx); + return RequestAuthorizationCode(); } } // don't know what to do, just forward response @@ -73,7 +73,7 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv NHttp::THeadersBuilder responseHeaders; responseHeaders.Parse(response->Headers); httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx) { @@ -87,17 +87,15 @@ void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBu token = tokenator->GetToken(Settings.SessionServiceTokenName); } httpRequest->Set("Authorization", token); // Bearer included - - TString bodyStr = body; - CGIEscape(bodyStr); - httpRequest->Set<&NHttp::THttpRequest::Body>(bodyStr); + httpRequest->Set<&NHttp::THttpRequest::Body>(body); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionServiceCheckNebius::StateExchange); } -void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::ExchangeSessionToken(TString& sessionToken, const NActors::TActorContext& ctx) { BLOG_D("Exchange session token"); + CGIEscape(sessionToken); TStringBuilder body; body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" @@ -107,8 +105,10 @@ void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString& sess SendTokenExchangeRequest(body, ETokenExchangeType::SessionToken, ctx); } -void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString& sessionToken, const TString& impersonatedToken, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(TString& sessionToken, TString& impersonatedToken, const NActors::TActorContext& ctx) { BLOG_D("Exchange impersonated token"); + CGIEscape(sessionToken); + CGIEscape(impersonatedToken); TStringBuilder body; body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" @@ -120,7 +120,7 @@ void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString& SendTokenExchangeRequest(body, ETokenExchangeType::ImpersonatedToken, ctx); } -void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie(const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie() { TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId); BLOG_D("Clear impersonated cookie (" << impersonatedCookieName << ") and retry"); NHttp::THeadersBuilder responseHeaders; @@ -129,17 +129,17 @@ void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie(const NActors::T responseHeaders.Set("Location", Request->URL); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("307", "Temporary Redirect", responseHeaders); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } -void THandlerSessionServiceCheckNebius::RequestAuthorizationCode(const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::RequestAuthorizationCode() { BLOG_D("Request authorization code"); NHttp::THttpOutgoingResponsePtr httpResponse = GetHttpOutgoingResponsePtr(Request, Settings); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } -void THandlerSessionServiceCheckNebius::ForwardUserRequest(TStringBuf authHeader, const NActors::TActorContext& ctx, bool secure) { - THandlerSessionServiceCheck::ForwardUserRequest(authHeader, ctx, secure); +void THandlerSessionServiceCheckNebius::ForwardUserRequest(TStringBuf authHeader, bool secure) { + THandlerSessionServiceCheck::ForwardUserRequest(authHeader, secure); Become(&THandlerSessionServiceCheckNebius::StateWork); } diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h index 8909607885e0..8407f1b92673 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h @@ -24,29 +24,29 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); void StartOidcProcess(const NActors::TActorContext& ctx) override; - void HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx); + void HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event); STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } STFUNC(StateExchange) { switch (ev->GetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleExchange); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleExchange); cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } private: void SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx); - void ExchangeSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx); - void ExchangeImpersonatedToken(const TString& sessionToken, const TString& impersonatedToken, const NActors::TActorContext& ctx); - void ClearImpersonatedCookie(const NActors::TActorContext& ctx); - void RequestAuthorizationCode(const NActors::TActorContext& ctx); - void ForwardUserRequest(TStringBuf authHeader, const NActors::TActorContext& ctx, bool secure = false) override; + void ExchangeSessionToken(TString& sessionToken, const NActors::TActorContext& ctx); + void ExchangeImpersonatedToken(TString& sessionToken, TString& impersonatedToken, const NActors::TActorContext& ctx); + void ClearImpersonatedCookie(); + void RequestAuthorizationCode(); + void ForwardUserRequest(TStringBuf authHeader, bool secure = false) override; bool NeedSendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response) const override; }; diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp index e8b50d2bb273..6f317e081a49 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp @@ -21,21 +21,21 @@ void THandlerSessionServiceCheckYandex::Bootstrap(const NActors::TActorContext& Become(&THandlerSessionServiceCheckYandex::StateWork); } -void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvCheckSessionResponse::TPtr event, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvCheckSessionResponse::TPtr event) { BLOG_D("SessionService.Check(): OK"); auto response = event->Get()->Response; const auto& iamToken = response.iam_token(); const TString authHeader = IAM_TOKEN_SCHEME + iamToken.iam_token(); - ForwardUserRequest(authHeader, ctx); + ForwardUserRequest(authHeader); } -void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvErrorResponse::TPtr event, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvErrorResponse::TPtr event) { BLOG_D("SessionService.Check(): " << event->Get()->Status); NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Status == "400") { - return ReplyAndDie(GetHttpOutgoingResponsePtr(Request, Settings), ctx); + return ReplyAndPassAway(GetHttpOutgoingResponsePtr(Request, Settings)); } else { - return ReplyAndDie(Request->CreateResponse( event->Get()->Status, event->Get()->Message, "text/plain", event->Get()->Details), ctx); + return ReplyAndPassAway(Request->CreateResponse( event->Get()->Status, event->Get()->Message, "text/plain", event->Get()->Details)); } } diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h index d0233d48274b..591c394a204c 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h @@ -20,14 +20,14 @@ class THandlerSessionServiceCheckYandex : public THandlerSessionServiceCheck { void Bootstrap(const NActors::TActorContext& ctx) override; - void Handle(TEvPrivate::TEvCheckSessionResponse::TPtr event, const NActors::TActorContext& ctx); - void Handle(TEvPrivate::TEvErrorResponse::TPtr event, const NActors::TActorContext& ctx); + void Handle(TEvPrivate::TEvCheckSessionResponse::TPtr event); + void Handle(TEvPrivate::TEvErrorResponse::TPtr event); STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); - HFunc(TEvPrivate::TEvCheckSessionResponse, Handle); - HFunc(TEvPrivate::TEvErrorResponse, Handle); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); + hFunc(TEvPrivate::TEvCheckSessionResponse, Handle); + hFunc(TEvPrivate::TEvErrorResponse, Handle); cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp b/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp index 63a9d79d8979..47c5443bc1f1 100644 --- a/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp +++ b/ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp @@ -1,11 +1,3 @@ -#include -#include -#include -#include -#include -#include -#include -#include #include "oidc_protected_page_handler.h" #include "oidc_session_create_handler.h" #include "oidc_impersonate_start_page_nebius.h" @@ -13,6 +5,14 @@ #include "oidc_settings.h" #include "openid_connect.h" #include "context.h" +#include +#include +#include +#include +#include +#include +#include +#include using namespace NMVP::NOIDC; @@ -633,7 +633,7 @@ Y_UNIT_TEST_SUITE(Mvp) { const NActors::TActorId sessionCreator = runtime.Register(new TSessionCreateHandler(edge, settings)); incomingRequest = new NHttp::THttpIncomingRequest(); TStringBuilder request; - request << "GET /auth/callback?code=code_template&state=" << state << " HTTP/1.1\r\n"; + request << "GET /auth/callback?code=code_template#&state=" << state << " HTTP/1.1\r\n"; request << "Host: " + hostProxy + "\r\n"; request << "Cookie: " << setCookie.NextTok(";") << "\r\n"; EatWholeString(incomingRequest, redirectStrategy.CreateRequest(request)); @@ -641,8 +641,8 @@ Y_UNIT_TEST_SUITE(Mvp) { auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); + UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template%23"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); const TString authorizationServerResponse = R"___({"access_token":"access_token_value","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); @@ -724,7 +724,7 @@ Y_UNIT_TEST_SUITE(Mvp) { } const TString hostProxy = "oidcproxy.net"; TStringBuilder request; - request << "GET /auth/callback?code=code_template&state=" << wrongState << " HTTP/1.1\r\n"; + request << "GET /auth/callback?code=code_template#&state=" << wrongState << " HTTP/1.1\r\n"; request << "Host: " + hostProxy + "\r\n"; TString cookie = context.CreateYdbOidcCookie(settings.ClientSecret); TStringBuf cookieBuf(cookie); @@ -778,7 +778,7 @@ Y_UNIT_TEST_SUITE(Mvp) { TContext context({.State = "test_state", .RequestedAddress = "/requested/page", .AjaxRequest = false}); TStringBuilder request; - request << "GET /auth/callback?code=code_template&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; + request << "GET /auth/callback?code=code_template#&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; request << "Host: oidcproxy.net\r\n"; TString cookie = context.CreateYdbOidcCookie(settings.ClientSecret); TStringBuf cookieBuf(cookie); @@ -793,8 +793,8 @@ Y_UNIT_TEST_SUITE(Mvp) { TAutoPtr handle; auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); + UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template%23"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); const TString authorizationServerResponse = R"___({"access_token":"access_token_value","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); @@ -832,7 +832,7 @@ Y_UNIT_TEST_SUITE(Mvp) { const NActors::TActorId sessionCreator = runtime.Register(new TSessionCreateHandler(edge, settings)); TContext context({.State = "test_state", .RequestedAddress = "/requested/page", .AjaxRequest = redirectStrategy.IsAjaxRequest()}); TStringBuilder request; - request << "GET /auth/callback?code=code_template&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; + request << "GET /auth/callback?code=code_template#&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; request << "Host: oidcproxy.net\r\n"; TString cookie = context.CreateYdbOidcCookie(settings.ClientSecret); TStringBuf cookieBuf(cookie); @@ -848,8 +848,8 @@ Y_UNIT_TEST_SUITE(Mvp) { TAutoPtr handle; auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); + UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template%23"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); const TString authorizationServerResponse = R"___({"access_token":"invalid_access_token","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); @@ -899,7 +899,7 @@ Y_UNIT_TEST_SUITE(Mvp) { TContext context({.State = "test_state", .RequestedAddress = "/requested/page", .AjaxRequest = false}); TStringBuilder request; - request << "GET /callback?code=code_template&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; + request << "GET /callback?code=code_template#&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; request << "Host: oidcproxy.net\r\n"; TString cookie = context.CreateYdbOidcCookie(settings.ClientSecret); TStringBuf cookieBuf(cookie); @@ -915,8 +915,8 @@ Y_UNIT_TEST_SUITE(Mvp) { auto outgoingRequestEv = runtime.GrabEdgeEvent(handle); const TStringBuf& body = outgoingRequestEv->Request->Body; - UNIT_ASSERT_STRING_CONTAINS(body, "code%3Dcode_template"); - UNIT_ASSERT_STRING_CONTAINS(body, "grant_type%3Dauthorization_code"); + UNIT_ASSERT_STRING_CONTAINS(body, "code=code_template%23"); + UNIT_ASSERT_STRING_CONTAINS(body, "grant_type=authorization_code"); const TString authorizationServerResponse = R"___({"access_token":"access_token_value","token_type":"bearer","expires_in":43199,"scope":"openid","id_token":"id_token_value"})___"; NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request); @@ -1062,7 +1062,7 @@ Y_UNIT_TEST_SUITE(Mvp) { TContext context({.State = "good_state", .RequestedAddress = "/requested/page", .AjaxRequest = false}); const TString hostProxy = "oidcproxy.net"; TStringBuilder request; - request << "GET /auth/callback?code=code_template&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; + request << "GET /auth/callback?code=code_template#&state=" << context.GetState(settings.ClientSecret) << " HTTP/1.1\r\n"; request << "Host: " + hostProxy + "\r\n"; NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest(); EatWholeString(incomingRequest, request); @@ -1106,7 +1106,7 @@ Y_UNIT_TEST_SUITE(Mvp) { } const TString hostProxy = "oidcproxy.net"; TStringBuilder request; - request << "GET /auth/callback?code=code_template&state=" << wrongState << " HTTP/1.1\r\n"; + request << "GET /auth/callback?code=code_template#&state=" << wrongState << " HTTP/1.1\r\n"; request << "Host: " + hostProxy + "\r\n"; TString cookie = context.CreateYdbOidcCookie(settings.ClientSecret); TStringBuf cookieBuf(cookie); diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.cpp b/ydb/mvp/oidc_proxy/oidc_session_create.cpp index 1b2129415c42..4a7d85ccc2fb 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create.cpp @@ -35,7 +35,7 @@ void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { if (restoreContextResult.IsSuccess()) { if (code.empty()) { LOG_DEBUG_S(ctx, NMVP::EService::MVP, "Restore oidc session failed: receive empty 'code' parameter"); - RetryRequestToProtectedResourceAndDie(ctx); + RetryRequestToProtectedResourceAndDie(); } else { RequestSessionToken(code, ctx); } @@ -43,17 +43,17 @@ void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { const auto& restoreSessionStatus = restoreContextResult.Status; LOG_DEBUG_S(ctx, NMVP::EService::MVP, restoreSessionStatus.ErrorMessage); if (restoreSessionStatus.IsErrorRetryable) { - RetryRequestToProtectedResourceAndDie(ctx); + RetryRequestToProtectedResourceAndDie(); } else { - SendUnknownErrorResponseAndDie(ctx); + SendUnknownErrorResponseAndDie(); } } } else { LOG_DEBUG_S(ctx, NMVP::EService::MVP, checkStateResult.ErrorMessage); if (restoreContextResult.IsSuccess() || restoreContextResult.Status.IsErrorRetryable) { - RetryRequestToProtectedResourceAndDie(ctx); + RetryRequestToProtectedResourceAndDie(); } else { - SendUnknownErrorResponseAndDie(ctx); + SendUnknownErrorResponseAndDie(); } } @@ -93,7 +93,7 @@ void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse: responseHeaders.Set("Content-Type", "text/plain"); httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); } - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } TString THandlerSessionCreate::ChangeSameSiteFieldInSessionCookie(const TString& cookie) { @@ -109,18 +109,18 @@ TString THandlerSessionCreate::ChangeSameSiteFieldInSessionCookie(const TString& return cookieBuilder; } -void THandlerSessionCreate::RetryRequestToProtectedResourceAndDie(const NActors::TActorContext& ctx) { +void THandlerSessionCreate::RetryRequestToProtectedResourceAndDie() { NHttp::THeadersBuilder responseHeaders; - RetryRequestToProtectedResourceAndDie(&responseHeaders, ctx); + RetryRequestToProtectedResourceAndDie(&responseHeaders); } -void THandlerSessionCreate::RetryRequestToProtectedResourceAndDie(NHttp::THeadersBuilder* responseHeaders, const NActors::TActorContext& ctx) { +void THandlerSessionCreate::RetryRequestToProtectedResourceAndDie(NHttp::THeadersBuilder* responseHeaders) { SetCORS(Request, responseHeaders); responseHeaders->Set("Location", Context.GetRequestedAddress()); - ReplyAndDie(Request->CreateResponse("302", "Found", *responseHeaders), ctx); + ReplyAndPassAway(Request->CreateResponse("302", "Found", *responseHeaders)); } -void THandlerSessionCreate::SendUnknownErrorResponseAndDie(const NActors::TActorContext& ctx) { +void THandlerSessionCreate::SendUnknownErrorResponseAndDie() { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/html"); SetCORS(Request, &responseHeaders); @@ -138,12 +138,12 @@ void THandlerSessionCreate::SendUnknownErrorResponseAndDie(const NActors::TActor "" "" ""; - ReplyAndDie(Request->CreateResponse("400", "Bad Request", responseHeaders, BAD_REQUEST_HTML_PAGE), ctx); + ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, BAD_REQUEST_HTML_PAGE)); } -void THandlerSessionCreate::ReplyAndDie(NHttp::THttpOutgoingResponsePtr httpResponse, const NActors::TActorContext& ctx) { - ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); - Die(ctx); +void THandlerSessionCreate::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + PassAway(); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.h b/ydb/mvp/oidc_proxy/oidc_session_create.h index c0a5045ef1ce..7d4c0f35c53b 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create.h @@ -28,7 +28,7 @@ class THandlerSessionCreate : public NActors::TActorBootstrappedHost; + CGIEscape(code); + + TStringBuilder body; body << "code=" << code - << "&client_id=" << Settings.ClientId + << "&client_id=" << code << "&grant_type=authorization_code" << "&redirect_uri=" << (Request->Endpoint->Secure ? "https://" : "http://") @@ -28,16 +30,13 @@ void THandlerSessionCreateNebius::RequestSessionToken(const TString& code, const NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetTokenEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); httpRequest->Set("Authorization", Settings.GetAuthorizationString()); - - TString bodyStr = body; - CGIEscape(bodyStr); - httpRequest->Set<&NHttp::THttpRequest::Body>(bodyStr); + httpRequest->Set<&NHttp::THttpRequest::Body>(body); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionCreateNebius::StateWork); } -void THandlerSessionCreateNebius::ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) { +void THandlerSessionCreateNebius::ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ) { TString sessionCookieName = CreateNameSessionCookie(Settings.ClientId); TString sessionCookieValue = Base64Encode(sessionToken); BLOG_D("Set session cookie: (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); @@ -47,7 +46,7 @@ void THandlerSessionCreateNebius::ProcessSessionToken(const TString& sessionToke responseHeaders.Set("Location", Context.GetRequestedAddress()); NHttp::THttpOutgoingResponsePtr httpResponse; httpResponse = Request->CreateResponse("302", "Cookie set", responseHeaders); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h index 38202f290f42..73977c698a5f 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h @@ -16,7 +16,7 @@ class THandlerSessionCreateNebius : public THandlerSessionCreate { const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - void RequestSessionToken(const TString& code, const NActors::TActorContext& ctx) override; + void RequestSessionToken(TString& code, const NActors::TActorContext& ctx) override; void ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) override; private: diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp index 28a3b3be0a1b..ec7fcb73140e 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp @@ -17,13 +17,17 @@ THandlerSessionCreateYandex::THandlerSessionCreateYandex(const NActors::TActorId : THandlerSessionCreate(sender, request, httpProxyId, settings) {} -void THandlerSessionCreateYandex::RequestSessionToken(const TString& code, const NActors::TActorContext& ctx) { +void THandlerSessionCreateYandex::RequestSessionToken(TString& code, const NActors::TActorContext& ctx) { NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetTokenEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); httpRequest->Set("Authorization", Settings.GetAuthorizationString()); - TString body = "grant_type=authorization_code&code=" + code; - CGIEscape(body); + + CGIEscape(code); + TStringBuilder body; + body << "grant_type=authorization_code" + << "&code=" << code; httpRequest->Set<&NHttp::THttpRequest::Body>(body); + ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionCreateYandex::StateWork); } @@ -56,26 +60,26 @@ void THandlerSessionCreateYandex::ProcessSessionToken(const TString& sessionToke connection->DoRequest(requestCreate, std::move(responseCb), &yandex::cloud::priv::oauth::v1::SessionService::Stub::AsyncCreate, meta); } -void THandlerSessionCreateYandex::HandleCreateSession(TEvPrivate::TEvCreateSessionResponse::TPtr event, const NActors::TActorContext& ctx) { +void THandlerSessionCreateYandex::HandleCreateSession(TEvPrivate::TEvCreateSessionResponse::TPtr event) { BLOG_D("SessionService.Create(): OK"); auto response = event->Get()->Response; NHttp::THeadersBuilder responseHeaders; for (const auto& cookie : response.Getset_cookie_header()) { responseHeaders.Set("Set-Cookie", ChangeSameSiteFieldInSessionCookie(cookie)); } - RetryRequestToProtectedResourceAndDie(&responseHeaders, ctx); + RetryRequestToProtectedResourceAndDie(&responseHeaders); } -void THandlerSessionCreateYandex::HandleError(TEvPrivate::TEvErrorResponse::TPtr event, const NActors::TActorContext& ctx) { +void THandlerSessionCreateYandex::HandleError(TEvPrivate::TEvErrorResponse::TPtr event) { BLOG_D("SessionService.Create(): " << event->Get()->Status); if (event->Get()->Status == "400") { - RetryRequestToProtectedResourceAndDie(ctx); + RetryRequestToProtectedResourceAndDie(); } else { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse( event->Get()->Status, event->Get()->Message, responseHeaders, event->Get()->Details); - ReplyAndDie(httpResponse, ctx); + ReplyAndPassAway(httpResponse); } } diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h index 26efa7792f74..5f92e5fb8a27 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h @@ -18,17 +18,17 @@ class THandlerSessionCreateYandex : public THandlerSessionCreate { const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - void RequestSessionToken(const TString& code, const NActors::TActorContext& ctx) override; + void RequestSessionToken(TString& code, const NActors::TActorContext& ctx) override; void ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) override; - void HandleCreateSession(TEvPrivate::TEvCreateSessionResponse::TPtr event, const NActors::TActorContext& ctx); - void HandleError(TEvPrivate::TEvErrorResponse::TPtr event, const NActors::TActorContext& ctx); + void HandleCreateSession(TEvPrivate::TEvCreateSessionResponse::TPtr event); + void HandleError(TEvPrivate::TEvErrorResponse::TPtr event); private: STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); - HFunc(TEvPrivate::TEvCreateSessionResponse, HandleCreateSession); - HFunc(TEvPrivate::TEvErrorResponse, HandleError); + hFunc(TEvPrivate::TEvCreateSessionResponse, HandleCreateSession); + hFunc(TEvPrivate::TEvErrorResponse, HandleError); cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_settings.cpp b/ydb/mvp/oidc_proxy/oidc_settings.cpp index ec02e593b038..4df4563b98da 100644 --- a/ydb/mvp/oidc_proxy/oidc_settings.cpp +++ b/ydb/mvp/oidc_proxy/oidc_settings.cpp @@ -1,6 +1,6 @@ -#include -#include #include "oidc_settings.h" +#include +#include namespace NMVP::NOIDC { diff --git a/ydb/mvp/oidc_proxy/oidc_settings.h b/ydb/mvp/oidc_proxy/oidc_settings.h index 47925ddb803c..87a90067c76e 100644 --- a/ydb/mvp/oidc_proxy/oidc_settings.h +++ b/ydb/mvp/oidc_proxy/oidc_settings.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include namespace NMVP::NOIDC { diff --git a/ydb/mvp/oidc_proxy/openid_connect.cpp b/ydb/mvp/oidc_proxy/openid_connect.cpp index b108899f8682..bfc93e2c188e 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.cpp +++ b/ydb/mvp/oidc_proxy/openid_connect.cpp @@ -1,15 +1,15 @@ -#include -#include -#include +#include "context.h" +#include "openid_connect.h" +#include "oidc_settings.h" +#include #include #include -#include #include #include #include -#include "context.h" -#include "openid_connect.h" -#include "oidc_settings.h" +#include +#include +#include namespace NMVP::NOIDC { @@ -242,7 +242,7 @@ TString DecodeToken(const TStringBuf& cookie) { try { Base64StrictDecode(cookie, token); } catch (std::exception& e) { - BLOG_D("Base64Decode " << cookie << " cookie: " << e.what()); + BLOG_D("Base64Decode " << NKikimr::MaskTicket(cookie) << " cookie: " << e.what()); token.clear(); } return token; diff --git a/ydb/mvp/oidc_proxy/openid_connect.h b/ydb/mvp/oidc_proxy/openid_connect.h index 3c3e8171be22..76b639115098 100644 --- a/ydb/mvp/oidc_proxy/openid_connect.h +++ b/ydb/mvp/oidc_proxy/openid_connect.h @@ -1,13 +1,13 @@ #pragma once -#include -#include -#include +#include "context.h" #include #include #include #include #include -#include "context.h" +#include +#include +#include namespace NMVP::NOIDC { From 5d15b4388056a547c79bc4cc572102936efeb206 Mon Sep 17 00:00:00 2001 From: StekPerepolnen Date: Wed, 27 Nov 2024 15:27:58 +0000 Subject: [PATCH 6/7] remove namespace --- ydb/mvp/oidc_proxy/oidc_client.cpp | 2 - .../oidc_impersonate_start_page_nebius.cpp | 16 +++---- .../oidc_impersonate_start_page_nebius.h | 6 +-- .../oidc_impersonate_stop_page_nebius.cpp | 5 +- .../oidc_impersonate_stop_page_nebius.h | 5 +- ydb/mvp/oidc_proxy/oidc_protected_page.cpp | 2 +- .../oidc_proxy/oidc_protected_page_handler.h | 7 ++- .../oidc_proxy/oidc_protected_page_nebius.cpp | 47 +++++++++---------- .../oidc_proxy/oidc_protected_page_nebius.h | 6 +-- .../oidc_proxy/oidc_protected_page_yandex.h | 3 -- ydb/mvp/oidc_proxy/oidc_session_create.cpp | 4 +- .../oidc_proxy/oidc_session_create_handler.h | 5 +- .../oidc_proxy/oidc_session_create_nebius.cpp | 20 ++++---- .../oidc_proxy/oidc_session_create_nebius.h | 3 -- .../oidc_proxy/oidc_session_create_yandex.cpp | 2 +- .../oidc_proxy/oidc_session_create_yandex.h | 3 -- 16 files changed, 54 insertions(+), 82 deletions(-) diff --git a/ydb/mvp/oidc_proxy/oidc_client.cpp b/ydb/mvp/oidc_proxy/oidc_client.cpp index 5da68afe01d9..0277b80ebda4 100644 --- a/ydb/mvp/oidc_proxy/oidc_client.cpp +++ b/ydb/mvp/oidc_proxy/oidc_client.cpp @@ -6,8 +6,6 @@ namespace NMVP::NOIDC { -using namespace NActors; - void InitOIDC(NActors::TActorSystem& actorSystem, const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) { diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp index 5c3de4b018e0..7139b465894e 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp @@ -62,12 +62,10 @@ void THandlerImpersonateStart::RequestImpersonatedToken(TString& sessionToken, T } httpRequest->Set("Authorization", token); // Bearer included - CGIEscape(sessionToken); - CGIEscape(serviceAccountId); - TStringBuilder body; - body << "session=" << sessionToken - << "&service_account_id=" << serviceAccountId; - httpRequest->Set<&NHttp::THttpRequest::Body>(body); + TCgiParameters params; + params.InsertEscaped("session", sessionToken); + params.InsertEscaped("service_account_id", serviceAccountId); + httpRequest->Set<&NHttp::THttpRequest::Body>(params()); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerImpersonateStart::StateWork); @@ -82,7 +80,7 @@ void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersona responseHeaders.Set("Set-Cookie", CreateSecureCookie(impersonatedCookieName, impersonatedCookieValue)); SetCORS(Request, &responseHeaders); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("200", "OK", responseHeaders); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) { @@ -128,7 +126,7 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon } void THandlerImpersonateStart::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { - Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(std::move(httpResponse))); PassAway(); } @@ -137,7 +135,7 @@ void THandlerImpersonateStart::ReplyBadRequestAndPassAway(const TString& errorMe responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } TImpersonateStartPageHandler::TImpersonateStartPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h index ed4ff9a831b7..eac60287b11b 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h @@ -2,11 +2,10 @@ #include "oidc_settings.h" #include "context.h" +#include namespace NMVP::NOIDC { -using namespace NActors; - class THandlerImpersonateStart : public NActors::TActorBootstrapped { private: using TBase = NActors::TActorBootstrapped; @@ -32,7 +31,6 @@ class THandlerImpersonateStart : public NActors::TActorBootstrappedGetTypeRewrite()) { hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; @@ -50,7 +48,7 @@ class TImpersonateStartPageHandler : public NActors::TActorGetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } }; diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp index 36305292d096..3c5b7111d3eb 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp @@ -1,7 +1,6 @@ #include "openid_connect.h" #include "oidc_session_create.h" #include "oidc_impersonate_stop_page_nebius.h" -#include namespace NMVP::NOIDC { @@ -25,11 +24,11 @@ void THandlerImpersonateStop::Bootstrap() { NHttp::THttpOutgoingResponsePtr httpResponse; httpResponse = Request->CreateResponse("200", "OK", responseHeaders); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } void THandlerImpersonateStop::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { - Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(std::move(httpResponse))); PassAway(); } diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h index 9f7fd296fbf9..a05c22bee833 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h @@ -2,11 +2,10 @@ #include "oidc_settings.h" #include "context.h" +#include namespace NMVP::NOIDC { -using namespace NActors; - class THandlerImpersonateStop : public NActors::TActorBootstrapped { private: using TBase = NActors::TActorBootstrapped; @@ -40,7 +39,7 @@ class TImpersonateStopPageHandler : public NActors::TActorGetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } }; diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp index bbef5c002d16..aa615ea48ff9 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp @@ -227,7 +227,7 @@ NHttp::THttpOutgoingResponsePtr THandlerSessionServiceCheck::CreateResponseForNo } void THandlerSessionServiceCheck::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { - Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(std::move(httpResponse))); PassAway(); } diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h b/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h index 67a193e99328..f3e904e814fb 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h @@ -1,14 +1,13 @@ #pragma once +#include "oidc_settings.h" #include +#include #include #include -#include "oidc_settings.h" namespace NMVP::NOIDC { -using namespace NActors; - class TProtectedPageHandler : public NActors::TActor { using TBase = NActors::TActor; @@ -22,7 +21,7 @@ class TProtectedPageHandler : public NActors::TActor { STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } }; diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp index e60797c6c70c..3ced86627b19 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp @@ -45,7 +45,7 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); - return ReplyAndPassAway(httpResponse); + return ReplyAndPassAway(std::move(httpResponse)); } NHttp::THttpIncomingResponsePtr response = event->Get()->Response; @@ -73,10 +73,10 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv NHttp::THeadersBuilder responseHeaders; responseHeaders.Parse(response->Headers); httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } -void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TCgiParameters& params, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx) { tokenExchangeType = exchangeType; NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -87,7 +87,7 @@ void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBu token = tokenator->GetToken(Settings.SessionServiceTokenName); } httpRequest->Set("Authorization", token); // Bearer included - httpRequest->Set<&NHttp::THttpRequest::Body>(body); + httpRequest->Set<&NHttp::THttpRequest::Body>(params()); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionServiceCheckNebius::StateExchange); @@ -95,29 +95,26 @@ void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TStringBu void THandlerSessionServiceCheckNebius::ExchangeSessionToken(TString& sessionToken, const NActors::TActorContext& ctx) { BLOG_D("Exchange session token"); - CGIEscape(sessionToken); - TStringBuilder body; - body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" - << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" - << "&subject_token_type=urn:ietf:params:oauth:token-type:session_token" - << "&subject_token=" << sessionToken; - - SendTokenExchangeRequest(body, ETokenExchangeType::SessionToken, ctx); + TCgiParameters params; + params.InsertEscaped("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"); + params.InsertEscaped("requested_token_type", "urn:ietf:params:oauth:token-type:access_token"); + params.InsertEscaped("subject_token_type", "urn:ietf:params:oauth:token-type:session_token"); + params.InsertEscaped("subject_token", sessionToken); + + SendTokenExchangeRequest(params, ETokenExchangeType::SessionToken, ctx); } void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(TString& sessionToken, TString& impersonatedToken, const NActors::TActorContext& ctx) { BLOG_D("Exchange impersonated token"); - CGIEscape(sessionToken); - CGIEscape(impersonatedToken); - TStringBuilder body; - body << "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" - << "&requested_token_type=urn:ietf:params:oauth:token-type:access_token" - << "&subject_token_type=urn:ietf:params:oauth:token-type:jwt" - << "&subject_token=" << impersonatedToken - << "&actor_token=" << sessionToken - << "&actor_token_type=urn:ietf:params:oauth:token-type:session_token"; - - SendTokenExchangeRequest(body, ETokenExchangeType::ImpersonatedToken, ctx); + TCgiParameters params; + params.InsertEscaped("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"); + params.InsertEscaped("requested_token_type", "urn:ietf:params:oauth:token-type:access_token"); + params.InsertEscaped("subject_token_type", "urn:ietf:params:oauth:token-type:jwt"); + params.InsertEscaped("subject_token", impersonatedToken); + params.InsertEscaped("actor_token", sessionToken); + params.InsertEscaped("actor_token_type", "urn:ietf:params:oauth:token-type:session_token"); + + SendTokenExchangeRequest(params, ETokenExchangeType::ImpersonatedToken, ctx); } void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie() { @@ -129,13 +126,13 @@ void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie() { responseHeaders.Set("Location", Request->URL); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("307", "Temporary Redirect", responseHeaders); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } void THandlerSessionServiceCheckNebius::RequestAuthorizationCode() { BLOG_D("Request authorization code"); NHttp::THttpOutgoingResponsePtr httpResponse = GetHttpOutgoingResponsePtr(Request, Settings); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } void THandlerSessionServiceCheckNebius::ForwardUserRequest(TStringBuf authHeader, bool secure) { diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h index 8407f1b92673..b7d60a11f4c6 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h @@ -4,8 +4,6 @@ namespace NMVP::NOIDC { -using namespace NActors; - class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { private: using TBase = THandlerSessionServiceCheck; @@ -29,19 +27,17 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } STFUNC(StateExchange) { switch (ev->GetTypeRewrite()) { hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleExchange); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } private: - void SendTokenExchangeRequest(const TStringBuilder& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx); + void SendTokenExchangeRequest(const TCgiParameters& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx); void ExchangeSessionToken(TString& sessionToken, const NActors::TActorContext& ctx); void ExchangeImpersonatedToken(TString& sessionToken, TString& impersonatedToken, const NActors::TActorContext& ctx); void ClearImpersonatedCookie(); diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h index 591c394a204c..f117106403cf 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_yandex.h @@ -5,8 +5,6 @@ namespace NMVP::NOIDC { -using namespace NActors; - class THandlerSessionServiceCheckYandex : public THandlerSessionServiceCheck { private: using TBase = THandlerSessionServiceCheck; @@ -28,7 +26,6 @@ class THandlerSessionServiceCheckYandex : public THandlerSessionServiceCheck { hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, HandleProxy); hFunc(TEvPrivate::TEvCheckSessionResponse, Handle); hFunc(TEvPrivate::TEvErrorResponse, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.cpp b/ydb/mvp/oidc_proxy/oidc_session_create.cpp index 4a7d85ccc2fb..e69c54ef8cf6 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create.cpp @@ -93,7 +93,7 @@ void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse: responseHeaders.Set("Content-Type", "text/plain"); httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); } - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } TString THandlerSessionCreate::ChangeSameSiteFieldInSessionCookie(const TString& cookie) { @@ -142,7 +142,7 @@ void THandlerSessionCreate::SendUnknownErrorResponseAndDie() { } void THandlerSessionCreate::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { - Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)); + Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(std::move(httpResponse))); PassAway(); } diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_handler.h b/ydb/mvp/oidc_proxy/oidc_session_create_handler.h index b8225f4bd7aa..8c1fc5c6875d 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_handler.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_handler.h @@ -1,14 +1,13 @@ #pragma once #include +#include #include #include #include "oidc_settings.h" namespace NMVP::NOIDC { -using namespace NActors; - class TSessionCreateHandler : public NActors::TActor { using TBase = NActors::TActor; @@ -22,7 +21,7 @@ class TSessionCreateHandler : public NActors::TActor { STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); + cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } }; diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp index 46cb1e16a9a4..7ac19dd18219 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp @@ -16,21 +16,19 @@ THandlerSessionCreateNebius::THandlerSessionCreateNebius(const NActors::TActorId void THandlerSessionCreateNebius::RequestSessionToken(TString& code, const NActors::TActorContext& ctx) { TStringBuf host = Request->Host; - CGIEscape(code); - TStringBuilder body; - body << "code=" << code - << "&client_id=" << code - << "&grant_type=authorization_code" - << "&redirect_uri=" - << (Request->Endpoint->Secure ? "https://" : "http://") - << host - << GetAuthCallbackUrl(); + TCgiParameters params; + params.InsertEscaped("code", code); + params.InsertEscaped("client_id", code); + params.InsertEscaped("grant_type", "authorization_code"); + params.InsertEscaped("redirect_uri", TStringBuilder() << (Request->Endpoint->Secure ? "https://" : "http://") + << host + << GetAuthCallbackUrl()); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetTokenEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); httpRequest->Set("Authorization", Settings.GetAuthorizationString()); - httpRequest->Set<&NHttp::THttpRequest::Body>(body); + httpRequest->Set<&NHttp::THttpRequest::Body>(params()); ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionCreateNebius::StateWork); @@ -46,7 +44,7 @@ void THandlerSessionCreateNebius::ProcessSessionToken(const TString& sessionToke responseHeaders.Set("Location", Context.GetRequestedAddress()); NHttp::THttpOutgoingResponsePtr httpResponse; httpResponse = Request->CreateResponse("302", "Cookie set", responseHeaders); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h index 73977c698a5f..1466e60ae063 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h @@ -4,8 +4,6 @@ namespace NMVP::NOIDC { -using namespace NActors; - class THandlerSessionCreateNebius : public THandlerSessionCreate { private: using TBase = THandlerSessionCreate; @@ -23,7 +21,6 @@ class THandlerSessionCreateNebius : public THandlerSessionCreate { STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp index ec7fcb73140e..3809fea07e7d 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp @@ -79,7 +79,7 @@ void THandlerSessionCreateYandex::HandleError(TEvPrivate::TEvErrorResponse::TPtr responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse( event->Get()->Status, event->Get()->Message, responseHeaders, event->Get()->Details); - ReplyAndPassAway(httpResponse); + ReplyAndPassAway(std::move(httpResponse)); } } diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h index 5f92e5fb8a27..ac8cb29c4d46 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h @@ -5,8 +5,6 @@ namespace NMVP::NOIDC { -using namespace NActors; - class THandlerSessionCreateYandex : public THandlerSessionCreate { private: using TBase = THandlerSessionCreate; @@ -29,7 +27,6 @@ class THandlerSessionCreateYandex : public THandlerSessionCreate { HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle); hFunc(TEvPrivate::TEvCreateSessionResponse, HandleCreateSession); hFunc(TEvPrivate::TEvErrorResponse, HandleError); - cFunc(TEvents::TEvPoisonPill::EventType, PassAway); } } }; From 7d3af5d39a6a3d65224cbaad04605a0929bc836a Mon Sep 17 00:00:00 2001 From: StekPerepolnen Date: Thu, 28 Nov 2024 15:49:08 +0000 Subject: [PATCH 7/7] return const --- .../oidc_impersonate_start_page_nebius.cpp | 32 ++++------- .../oidc_impersonate_start_page_nebius.h | 8 +-- .../oidc_impersonate_stop_page_nebius.cpp | 8 +-- .../oidc_impersonate_stop_page_nebius.h | 4 +- ydb/mvp/oidc_proxy/oidc_protected_page.cpp | 2 +- .../oidc_protected_page_handler.cpp | 6 +- .../oidc_proxy/oidc_protected_page_handler.h | 4 +- .../oidc_proxy/oidc_protected_page_nebius.cpp | 57 ++++++++----------- .../oidc_proxy/oidc_protected_page_nebius.h | 6 +- ydb/mvp/oidc_proxy/oidc_session_create.cpp | 26 ++++----- ydb/mvp/oidc_proxy/oidc_session_create.h | 4 +- .../oidc_session_create_handler.cpp | 8 +-- .../oidc_proxy/oidc_session_create_handler.h | 4 +- .../oidc_proxy/oidc_session_create_nebius.cpp | 17 +++--- .../oidc_proxy/oidc_session_create_nebius.h | 2 +- .../oidc_proxy/oidc_session_create_yandex.cpp | 17 +++--- .../oidc_proxy/oidc_session_create_yandex.h | 2 +- 17 files changed, 90 insertions(+), 117 deletions(-) diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp index 7139b465894e..d23265864d12 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -20,7 +19,7 @@ THandlerImpersonateStart::THandlerImpersonateStart(const NActors::TActorId& send , Settings(settings) {} -void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { +void THandlerImpersonateStart::Bootstrap() { BLOG_D("Start impersonation process"); NHttp::TUrlParameters urlParameters(Request->URL); @@ -29,11 +28,7 @@ void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { NHttp::THeaders headers(Request->Headers); NHttp::TCookies cookies(headers.Get("Cookie")); - TString sessionCookieName = CreateNameSessionCookie(Settings.ClientId); - TStringBuf sessionCookieValue = cookies.Get(sessionCookieName); - if (!sessionCookieValue.Empty()) { - BLOG_D("Using session cookie (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")"); - } + TStringBuf sessionCookieValue = GetCookie(cookies, CreateNameSessionCookie(Settings.ClientId)); TString sessionToken = DecodeToken(sessionCookieValue); TStringBuf impersonatedCookieValue = GetCookie(cookies, CreateNameImpersonatedCookie(Settings.ClientId)); @@ -47,10 +42,10 @@ void THandlerImpersonateStart::Bootstrap(const NActors::TActorContext& ctx) { return ReplyBadRequestAndPassAway("Wrong impersonate parameter: service_account_id not found"); } - RequestImpersonatedToken(sessionToken, serviceAccountId, ctx); + RequestImpersonatedToken(sessionToken, serviceAccountId); } -void THandlerImpersonateStart::RequestImpersonatedToken(TString& sessionToken, TString& serviceAccountId, const NActors::TActorContext& ctx) { +void THandlerImpersonateStart::RequestImpersonatedToken(TString& sessionToken, TString& serviceAccountId) { BLOG_D("Request impersonated token"); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetImpersonateEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -63,11 +58,11 @@ void THandlerImpersonateStart::RequestImpersonatedToken(TString& sessionToken, T httpRequest->Set("Authorization", token); // Bearer included TCgiParameters params; - params.InsertEscaped("session", sessionToken); - params.InsertEscaped("service_account_id", serviceAccountId); + params.emplace("session", sessionToken); + params.emplace("service_account_id", serviceAccountId); httpRequest->Set<&NHttp::THttpRequest::Body>(params()); - ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerImpersonateStart::StateWork); } @@ -79,14 +74,12 @@ void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersona NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Set-Cookie", CreateSecureCookie(impersonatedCookieName, impersonatedCookieValue)); SetCORS(Request, &responseHeaders); - NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("200", "OK", responseHeaders); - ReplyAndPassAway(std::move(httpResponse)); + ReplyAndPassAway(Request->CreateResponse("200", "OK", responseHeaders)); } void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) { - NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Error.empty() && event->Get()->Response) { - NHttp::THttpIncomingResponsePtr response = event->Get()->Response; + NHttp::THttpIncomingResponsePtr response = std::move(event->Get()->Response); BLOG_D("Incoming response from authorization server: " << response->Status); if (response->Status == "200") { TStringBuf errorMessage; @@ -134,8 +127,7 @@ void THandlerImpersonateStart::ReplyBadRequestAndPassAway(const TString& errorMe NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); - NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage); - ReplyAndPassAway(std::move(httpResponse)); + ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage)); } TImpersonateStartPageHandler::TImpersonateStartPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings) @@ -144,8 +136,8 @@ TImpersonateStartPageHandler::TImpersonateStartPageHandler(const NActors::TActor , Settings(settings) {} -void TImpersonateStartPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) { - ctx.Register(new THandlerImpersonateStart(event->Sender, event->Get()->Request, HttpProxyId, Settings)); +void TImpersonateStartPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event) { + Register(new THandlerImpersonateStart(event->Sender, event->Get()->Request, HttpProxyId, Settings)); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h index eac60287b11b..2c9c904d5a26 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h @@ -21,8 +21,8 @@ class THandlerImpersonateStart : public NActors::TActorBootstrappedGetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp index 3c5b7111d3eb..214b9b07dcf8 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.cpp @@ -22,9 +22,7 @@ void THandlerImpersonateStop::Bootstrap() { responseHeaders.Set("Set-Cookie", ClearSecureCookie(impersonatedCookieName)); SetCORS(Request, &responseHeaders); - NHttp::THttpOutgoingResponsePtr httpResponse; - httpResponse = Request->CreateResponse("200", "OK", responseHeaders); - ReplyAndPassAway(std::move(httpResponse)); + ReplyAndPassAway(Request->CreateResponse("200", "OK", responseHeaders)); } void THandlerImpersonateStop::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) { @@ -38,8 +36,8 @@ TImpersonateStopPageHandler::TImpersonateStopPageHandler(const NActors::TActorId , Settings(settings) {} -void TImpersonateStopPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) { - ctx.Register(new THandlerImpersonateStop(event->Sender, event->Get()->Request, HttpProxyId, Settings)); +void TImpersonateStopPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event) { + Register(new THandlerImpersonateStop(event->Sender, event->Get()->Request, HttpProxyId, Settings)); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h index a05c22bee833..f298ef7147ad 100644 --- a/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_impersonate_stop_page_nebius.h @@ -34,11 +34,11 @@ class TImpersonateStopPageHandler : public NActors::TActorGetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp index aa615ea48ff9..41bea328e805 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page.cpp @@ -33,7 +33,7 @@ void THandlerSessionServiceCheck::Bootstrap(const NActors::TActorContext& ctx) { void THandlerSessionServiceCheck::HandleProxy(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) { if (event->Get()->Response != nullptr) { - NHttp::THttpIncomingResponsePtr response = event->Get()->Response; + NHttp::THttpIncomingResponsePtr response = std::move(event->Get()->Response); BLOG_D("Incoming response for protected resource: " << response->Status); if (NeedSendSecureHttpRequest(response)) { return SendSecureHttpRequest(response); diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_handler.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_handler.cpp index 1f75f55a2ad4..cd4c6836a803 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_handler.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_handler.cpp @@ -10,13 +10,13 @@ TProtectedPageHandler::TProtectedPageHandler(const NActors::TActorId& httpProxyI , Settings(settings) {} -void TProtectedPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) { +void TProtectedPageHandler::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event) { switch (Settings.AccessServiceType) { case NMvp::yandex_v2: - ctx.Register(new THandlerSessionServiceCheckYandex(event->Sender, event->Get()->Request, HttpProxyId, Settings)); + Register(new THandlerSessionServiceCheckYandex(event->Sender, event->Get()->Request, HttpProxyId, Settings)); break; case NMvp::nebius_v1: - ctx.Register(new THandlerSessionServiceCheckNebius(event->Sender, event->Get()->Request, HttpProxyId, Settings)); + Register(new THandlerSessionServiceCheckNebius(event->Sender, event->Get()->Request, HttpProxyId, Settings)); break; } } diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h b/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h index f3e904e814fb..39ca40c5a598 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_handler.h @@ -16,11 +16,11 @@ class TProtectedPageHandler : public NActors::TActor { public: TProtectedPageHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx); + void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event); STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp index 3ced86627b19..449afb3abbe1 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include #include #include @@ -18,7 +16,7 @@ THandlerSessionServiceCheckNebius::THandlerSessionServiceCheckNebius(const NActo : THandlerSessionServiceCheck(sender, request, httpProxyId, settings) {} -void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorContext&) { NHttp::THeaders headers(Request->Headers); BLOG_D("Start OIDC process"); @@ -30,25 +28,24 @@ void THandlerSessionServiceCheckNebius::StartOidcProcess(const NActors::TActorCo if (sessionToken) { TString impersonatedToken = DecodeToken(impersonatedCookieValue); if (impersonatedToken) { - ExchangeImpersonatedToken(sessionToken, impersonatedToken, ctx); + ExchangeImpersonatedToken(sessionToken, impersonatedToken); } else { - ExchangeSessionToken(sessionToken, ctx); + ExchangeSessionToken(sessionToken); } } else{ RequestAuthorizationCode(); } } -void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) { +void THandlerSessionServiceCheckNebius::HandleExchange(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) { if (!event->Get()->Response) { BLOG_D("Getting access token: Bad Request"); NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); - NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); - return ReplyAndPassAway(std::move(httpResponse)); + return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error)); } - NHttp::THttpIncomingResponsePtr response = event->Get()->Response; + NHttp::THttpIncomingResponsePtr response = std::move(event->Get()->Response); BLOG_D("Getting access token: " << response->Status << " " << response->Message); if (response->Status == "200") { TString iamToken; @@ -69,14 +66,12 @@ void THandlerSessionServiceCheckNebius:: HandleExchange(NHttp::TEvHttpProxy::TEv } } // don't know what to do, just forward response - NHttp::THttpOutgoingResponsePtr httpResponse; NHttp::THeadersBuilder responseHeaders; responseHeaders.Parse(response->Headers); - httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); - ReplyAndPassAway(std::move(httpResponse)); + ReplyAndPassAway(Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body)); } -void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TCgiParameters& params, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TCgiParameters& params, const ETokenExchangeType exchangeType) { tokenExchangeType = exchangeType; NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetExchangeEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); @@ -89,32 +84,32 @@ void THandlerSessionServiceCheckNebius::SendTokenExchangeRequest(const TCgiParam httpRequest->Set("Authorization", token); // Bearer included httpRequest->Set<&NHttp::THttpRequest::Body>(params()); - ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionServiceCheckNebius::StateExchange); } -void THandlerSessionServiceCheckNebius::ExchangeSessionToken(TString& sessionToken, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString& sessionToken) { BLOG_D("Exchange session token"); TCgiParameters params; - params.InsertEscaped("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"); - params.InsertEscaped("requested_token_type", "urn:ietf:params:oauth:token-type:access_token"); - params.InsertEscaped("subject_token_type", "urn:ietf:params:oauth:token-type:session_token"); - params.InsertEscaped("subject_token", sessionToken); + params.emplace("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"); + params.emplace("requested_token_type", "urn:ietf:params:oauth:token-type:access_token"); + params.emplace("subject_token_type", "urn:ietf:params:oauth:token-type:session_token"); + params.emplace("subject_token", sessionToken); - SendTokenExchangeRequest(params, ETokenExchangeType::SessionToken, ctx); + SendTokenExchangeRequest(params, ETokenExchangeType::SessionToken); } -void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(TString& sessionToken, TString& impersonatedToken, const NActors::TActorContext& ctx) { +void THandlerSessionServiceCheckNebius::ExchangeImpersonatedToken(const TString& sessionToken, const TString& impersonatedToken) { BLOG_D("Exchange impersonated token"); TCgiParameters params; - params.InsertEscaped("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"); - params.InsertEscaped("requested_token_type", "urn:ietf:params:oauth:token-type:access_token"); - params.InsertEscaped("subject_token_type", "urn:ietf:params:oauth:token-type:jwt"); - params.InsertEscaped("subject_token", impersonatedToken); - params.InsertEscaped("actor_token", sessionToken); - params.InsertEscaped("actor_token_type", "urn:ietf:params:oauth:token-type:session_token"); - - SendTokenExchangeRequest(params, ETokenExchangeType::ImpersonatedToken, ctx); + params.emplace("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange"); + params.emplace("requested_token_type", "urn:ietf:params:oauth:token-type:access_token"); + params.emplace("subject_token_type", "urn:ietf:params:oauth:token-type:jwt"); + params.emplace("subject_token", impersonatedToken); + params.emplace("actor_token", sessionToken); + params.emplace("actor_token_type", "urn:ietf:params:oauth:token-type:session_token"); + + SendTokenExchangeRequest(params, ETokenExchangeType::ImpersonatedToken); } void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie() { @@ -124,9 +119,7 @@ void THandlerSessionServiceCheckNebius::ClearImpersonatedCookie() { SetCORS(Request, &responseHeaders); responseHeaders.Set("Set-Cookie", ClearSecureCookie(impersonatedCookieName)); responseHeaders.Set("Location", Request->URL); - - NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse("307", "Temporary Redirect", responseHeaders); - ReplyAndPassAway(std::move(httpResponse)); + ReplyAndPassAway(Request->CreateResponse("307", "Temporary Redirect", responseHeaders)); } void THandlerSessionServiceCheckNebius::RequestAuthorizationCode() { diff --git a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h index b7d60a11f4c6..035ba94db989 100644 --- a/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_protected_page_nebius.h @@ -37,9 +37,9 @@ class THandlerSessionServiceCheckNebius : public THandlerSessionServiceCheck { } private: - void SendTokenExchangeRequest(const TCgiParameters& body, const ETokenExchangeType exchangeType, const NActors::TActorContext& ctx); - void ExchangeSessionToken(TString& sessionToken, const NActors::TActorContext& ctx); - void ExchangeImpersonatedToken(TString& sessionToken, TString& impersonatedToken, const NActors::TActorContext& ctx); + void SendTokenExchangeRequest(const TCgiParameters& body, const ETokenExchangeType exchangeType); + void ExchangeSessionToken(const TString& sessionToken); + void ExchangeImpersonatedToken(const TString& sessionToken, const TString& impersonatedToken); void ClearImpersonatedCookie(); void RequestAuthorizationCode(); void ForwardUserRequest(TStringBuf authHeader, bool secure = false) override; diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.cpp b/ydb/mvp/oidc_proxy/oidc_session_create.cpp index e69c54ef8cf6..2f2695143fdf 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include "openid_connect.h" @@ -18,8 +17,8 @@ THandlerSessionCreate::THandlerSessionCreate(const NActors::TActorId& sender, , Settings(settings) {} -void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { - LOG_DEBUG_S(ctx, NMVP::EService::MVP, "Restore oidc session"); +void THandlerSessionCreate::Bootstrap() { + BLOG_D("Restore oidc session"); NHttp::TUrlParameters urlParameters(Request->URL); TString code = urlParameters["code"]; TString state = urlParameters["state"]; @@ -34,14 +33,14 @@ void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { if (checkStateResult.IsSuccess()) { if (restoreContextResult.IsSuccess()) { if (code.empty()) { - LOG_DEBUG_S(ctx, NMVP::EService::MVP, "Restore oidc session failed: receive empty 'code' parameter"); + BLOG_D("Restore oidc session failed: receive empty 'code' parameter"); RetryRequestToProtectedResourceAndDie(); } else { - RequestSessionToken(code, ctx); + RequestSessionToken(code); } } else { const auto& restoreSessionStatus = restoreContextResult.Status; - LOG_DEBUG_S(ctx, NMVP::EService::MVP, restoreSessionStatus.ErrorMessage); + BLOG_D(restoreSessionStatus.ErrorMessage); if (restoreSessionStatus.IsErrorRetryable) { RetryRequestToProtectedResourceAndDie(); } else { @@ -49,7 +48,7 @@ void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { } } } else { - LOG_DEBUG_S(ctx, NMVP::EService::MVP, checkStateResult.ErrorMessage); + BLOG_D(checkStateResult.ErrorMessage); if (restoreContextResult.IsSuccess() || restoreContextResult.Status.IsErrorRetryable) { RetryRequestToProtectedResourceAndDie(); } else { @@ -60,9 +59,8 @@ void THandlerSessionCreate::Bootstrap(const NActors::TActorContext& ctx) { } void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) { - NHttp::THttpOutgoingResponsePtr httpResponse; if (event->Get()->Error.empty() && event->Get()->Response) { - NHttp::THttpIncomingResponsePtr response = event->Get()->Response; + NHttp::THttpIncomingResponsePtr response = std::move(event->Get()->Response); BLOG_D("Incoming response from authorization server: " << response->Status); if (response->Status == "200") { TStringBuf errorMessage; @@ -72,8 +70,7 @@ void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse: const NJson::TJsonValue* jsonAccessToken; if (jsonValue.GetValuePointer("access_token", &jsonAccessToken)) { TString sessionToken = jsonAccessToken->GetStringRobust(); - ProcessSessionToken(sessionToken, ctx); - return; + return ProcessSessionToken(sessionToken, ctx); } else { errorMessage = "Wrong OIDC provider response: access_token not found"; } @@ -82,18 +79,17 @@ void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse: } NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); - httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage); + return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage)); } else { NHttp::THeadersBuilder responseHeaders; responseHeaders.Parse(response->Headers); - httpResponse = Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body); + return ReplyAndPassAway(Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body)); } } else { NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); - httpResponse = Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error); + return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error)); } - ReplyAndPassAway(std::move(httpResponse)); } TString THandlerSessionCreate::ChangeSameSiteFieldInSessionCookie(const TString& cookie) { diff --git a/ydb/mvp/oidc_proxy/oidc_session_create.h b/ydb/mvp/oidc_proxy/oidc_session_create.h index 7d4c0f35c53b..b45f96a36ccf 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create.h @@ -28,10 +28,10 @@ class THandlerSessionCreate : public NActors::TActorBootstrappedGet()->Request; if (request->Method == "GET") { switch (Settings.AccessServiceType) { case NMvp::yandex_v2: - ctx.Register(new THandlerSessionCreateYandex(event->Sender, request, HttpProxyId, Settings)); + Register(new THandlerSessionCreateYandex(event->Sender, request, HttpProxyId, Settings)); return; case NMvp::nebius_v1: - ctx.Register(new THandlerSessionCreateNebius(event->Sender, request, HttpProxyId, Settings)); + Register(new THandlerSessionCreateNebius(event->Sender, request, HttpProxyId, Settings)); return; } } auto response = request->CreateResponseBadRequest(); - ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response)); + Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response)); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_handler.h b/ydb/mvp/oidc_proxy/oidc_session_create_handler.h index 8c1fc5c6875d..8fdd2cb0958a 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_handler.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_handler.h @@ -16,11 +16,11 @@ class TSessionCreateHandler : public NActors::TActor { public: TSessionCreateHandler(const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx); + void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event); STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { - HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); + hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle); cFunc(NActors::TEvents::TEvPoisonPill::EventType, PassAway); } } diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp index 7ac19dd18219..5f8fdc66a72e 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp @@ -3,7 +3,6 @@ #include "openid_connect.h" #include "oidc_session_create_nebius.h" #include -#include namespace NMVP::NOIDC { @@ -14,14 +13,14 @@ THandlerSessionCreateNebius::THandlerSessionCreateNebius(const NActors::TActorId : THandlerSessionCreate(sender, request, httpProxyId, settings) {} -void THandlerSessionCreateNebius::RequestSessionToken(TString& code, const NActors::TActorContext& ctx) { +void THandlerSessionCreateNebius::RequestSessionToken(const TString& code) { TStringBuf host = Request->Host; TCgiParameters params; - params.InsertEscaped("code", code); - params.InsertEscaped("client_id", code); - params.InsertEscaped("grant_type", "authorization_code"); - params.InsertEscaped("redirect_uri", TStringBuilder() << (Request->Endpoint->Secure ? "https://" : "http://") + params.emplace("code", code); + params.emplace("client_id", code); + params.emplace("grant_type", "authorization_code"); + params.emplace("redirect_uri", TStringBuilder() << (Request->Endpoint->Secure ? "https://" : "http://") << host << GetAuthCallbackUrl()); @@ -30,7 +29,7 @@ void THandlerSessionCreateNebius::RequestSessionToken(TString& code, const NActo httpRequest->Set("Authorization", Settings.GetAuthorizationString()); httpRequest->Set<&NHttp::THttpRequest::Body>(params()); - ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionCreateNebius::StateWork); } @@ -42,9 +41,7 @@ void THandlerSessionCreateNebius::ProcessSessionToken(const TString& sessionToke NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Set-Cookie", CreateSecureCookie(sessionCookieName, sessionCookieValue)); responseHeaders.Set("Location", Context.GetRequestedAddress()); - NHttp::THttpOutgoingResponsePtr httpResponse; - httpResponse = Request->CreateResponse("302", "Cookie set", responseHeaders); - ReplyAndPassAway(std::move(httpResponse)); + ReplyAndPassAway(Request->CreateResponse("302", "Cookie set", responseHeaders)); } } // NMVP::NOIDC diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h index 1466e60ae063..7dcd8a1197b3 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_nebius.h @@ -14,7 +14,7 @@ class THandlerSessionCreateNebius : public THandlerSessionCreate { const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - void RequestSessionToken(TString& code, const NActors::TActorContext& ctx) override; + void RequestSessionToken(const TString& code) override; void ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) override; private: diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp index 3809fea07e7d..6a3c45420ddf 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "oidc_session_create_yandex.h" namespace NMVP { @@ -17,18 +16,17 @@ THandlerSessionCreateYandex::THandlerSessionCreateYandex(const NActors::TActorId : THandlerSessionCreate(sender, request, httpProxyId, settings) {} -void THandlerSessionCreateYandex::RequestSessionToken(TString& code, const NActors::TActorContext& ctx) { +void THandlerSessionCreateYandex::RequestSessionToken(const TString& code) { NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestPost(Settings.GetTokenEndpointURL()); httpRequest->Set<&NHttp::THttpRequest::ContentType>("application/x-www-form-urlencoded"); httpRequest->Set("Authorization", Settings.GetAuthorizationString()); - CGIEscape(code); - TStringBuilder body; - body << "grant_type=authorization_code" - << "&code=" << code; - httpRequest->Set<&NHttp::THttpRequest::Body>(body); + TCgiParameters params; + params.emplace("grant_type", "authorization_code"); + params.emplace("code", code); + httpRequest->Set<&NHttp::THttpRequest::Body>(params()); - ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); + Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)); Become(&THandlerSessionCreateYandex::StateWork); } @@ -78,8 +76,7 @@ void THandlerSessionCreateYandex::HandleError(TEvPrivate::TEvErrorResponse::TPtr NHttp::THeadersBuilder responseHeaders; responseHeaders.Set("Content-Type", "text/plain"); SetCORS(Request, &responseHeaders); - NHttp::THttpOutgoingResponsePtr httpResponse = Request->CreateResponse( event->Get()->Status, event->Get()->Message, responseHeaders, event->Get()->Details); - ReplyAndPassAway(std::move(httpResponse)); + ReplyAndPassAway(Request->CreateResponse( event->Get()->Status, event->Get()->Message, responseHeaders, event->Get()->Details)); } } diff --git a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h index ac8cb29c4d46..8114c29f78be 100644 --- a/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h +++ b/ydb/mvp/oidc_proxy/oidc_session_create_yandex.h @@ -16,7 +16,7 @@ class THandlerSessionCreateYandex : public THandlerSessionCreate { const NActors::TActorId& httpProxyId, const TOpenIdConnectSettings& settings); - void RequestSessionToken(TString& code, const NActors::TActorContext& ctx) override; + void RequestSessionToken(const TString& code) override; void ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) override; void HandleCreateSession(TEvPrivate::TEvCreateSessionResponse::TPtr event); void HandleError(TEvPrivate::TEvErrorResponse::TPtr event);