Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added max-age #13732

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 23 additions & 22 deletions ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,30 @@ void THandlerImpersonateStart::RequestImpersonatedToken(TString& sessionToken, T
Become(&THandlerImpersonateStart::StateWork);
}

void THandlerImpersonateStart::ProcessImpersonatedToken(const TString& impersonatedToken) {
void THandlerImpersonateStart::ProcessImpersonatedToken(const NJson::TJsonValue& jsonValue) {
const NJson::TJsonValue* jsonImpersonatedToken;
const NJson::TJsonValue* jsonExpiresIn;
TString impersonatedToken;
unsigned long long expiresIn;
if (!jsonValue.GetValuePointer("impersonation", &jsonImpersonatedToken)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: `impersonation` not found");
}
if (!jsonImpersonatedToken->GetString(&impersonatedToken)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: failed to extract `impersonation`");
}
if (!jsonValue.GetValuePointer("expires_in", &jsonExpiresIn)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: `expires_in` not found");
}
if (!jsonExpiresIn->GetUInteger(&expiresIn)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: failed to extract `expires_in`");
}
expiresIn = std::min(expiresIn, static_cast<unsigned long long>(TDuration::Days(7).Seconds())); // clean cookies no less than once a week.
TString impersonatedCookieName = CreateNameImpersonatedCookie(Settings.ClientId);
TString impersonatedCookieValue = Base64Encode(impersonatedToken);
BLOG_D("Set impersonated cookie: (" << impersonatedCookieName << ": " << NKikimr::MaskTicket(impersonatedCookieValue) << ")");

NHttp::THeadersBuilder responseHeaders;
responseHeaders.Set("Set-Cookie", CreateSecureCookie(impersonatedCookieName, impersonatedCookieValue));
responseHeaders.Set("Set-Cookie", CreateSecureCookie(impersonatedCookieName, impersonatedCookieValue, expiresIn));
SetCORS(Request, &responseHeaders);
ReplyAndPassAway(Request->CreateResponse("200", "OK", responseHeaders));
}
Expand All @@ -82,25 +99,12 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon
NHttp::THttpIncomingResponsePtr response = std::move(event->Get()->Response);
BLOG_D("Incoming response from authorization server: " << response->Status);
if (response->Status == "200") {
TStringBuf errorMessage;
NJson::TJsonValue jsonValue;
NJson::TJsonReaderConfig jsonConfig;
if (NJson::ReadJsonTree(response->Body, &jsonConfig, &jsonValue)) {
const NJson::TJsonValue* jsonImpersonatedToken;
if (jsonValue.GetValuePointer("impersonation", &jsonImpersonatedToken)) {
TString impersonatedToken = jsonImpersonatedToken->GetStringRobust();
ProcessImpersonatedToken(impersonatedToken);
return;
} else {
errorMessage = "Wrong OIDC provider response: impersonated token not found";
}
} else {
errorMessage = "Wrong OIDC response";
return ProcessImpersonatedToken(jsonValue);
}
NHttp::THeadersBuilder responseHeaders;
responseHeaders.Set("Content-Type", "text/plain");
SetCORS(Request, &responseHeaders);
return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage));
return ReplyBadRequestAndPassAway("Wrong OIDC response");
} else {
NHttp::THeadersBuilder responseHeaders;
NHttp::THeaders headers(response->Headers);
Expand All @@ -110,12 +114,9 @@ void THandlerImpersonateStart::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRespon
SetCORS(Request, &responseHeaders);
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 ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error));
}

ReplyBadRequestAndPassAway(event->Get()->Error);
}

void THandlerImpersonateStart::ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse) {
Expand Down
2 changes: 1 addition & 1 deletion ydb/mvp/oidc_proxy/oidc_impersonate_start_page_nebius.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class THandlerImpersonateStart : public NActors::TActorBootstrapped<THandlerImpe
const TOpenIdConnectSettings& settings);
void Bootstrap();
void RequestImpersonatedToken(TString&, TString&);
void ProcessImpersonatedToken(const TString& impersonatedToken);
void ProcessImpersonatedToken(const NJson::TJsonValue& jsonValue);
void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event);
void ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse);
void ReplyBadRequestAndPassAway(const TString& errorMessage);
Expand Down
4 changes: 2 additions & 2 deletions ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ Y_UNIT_TEST_SUITE(Mvp) {
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\"}"};
TString okResponseBody {"{\"impersonation\": \"impersonation_token\", \"expires_in\": 43200}"};
EatWholeString(incomingResponse, "HTTP/1.1 200 OK\r\n"
"Connection: close\r\n"
"Content-Type: text/html\r\n"
Expand All @@ -1182,7 +1182,7 @@ Y_UNIT_TEST_SUITE(Mvp) {
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"));
TString expectedCookie = CreateSecureCookie(CreateNameImpersonatedCookie(settings.ClientId), Base64Encode("impersonation_token"), 43200);
UNIT_ASSERT_STRINGS_EQUAL(impersonatedCookie, expectedCookie);
}

Expand Down
32 changes: 12 additions & 20 deletions ydb/mvp/oidc_proxy/oidc_session_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,40 +58,32 @@ void THandlerSessionCreate::Bootstrap() {

}

void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
void THandlerSessionCreate::ReplyBadRequestAndPassAway(TString errorMessage) {
NHttp::THeadersBuilder responseHeaders;
SetCORS(Request, &responseHeaders);
responseHeaders.Set("Content-Type", "text/plain");
return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage));
}

void THandlerSessionCreate::Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event) {
if (event->Get()->Error.empty() && 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;
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();
return ProcessSessionToken(sessionToken, ctx);
} else {
errorMessage = "Wrong OIDC provider response: access_token not found";
}
} else {
errorMessage = "Wrong OIDC response";
return ProcessSessionToken(jsonValue);
}
NHttp::THeadersBuilder responseHeaders;
SetCORS(Request, &responseHeaders);
responseHeaders.Set("Content-Type", "text/plain");
return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, errorMessage));
return ReplyBadRequestAndPassAway("Wrong OIDC response");
} else {
NHttp::THeadersBuilder responseHeaders;
responseHeaders.Parse(response->Headers);
return ReplyAndPassAway(Request->CreateResponse(response->Status, response->Message, responseHeaders, response->Body));
}
} else {
NHttp::THeadersBuilder responseHeaders;
SetCORS(Request, &responseHeaders);
responseHeaders.Set("Content-Type", "text/plain");
return ReplyAndPassAway(Request->CreateResponse("400", "Bad Request", responseHeaders, event->Get()->Error));
}

return ReplyBadRequestAndPassAway(event->Get()->Error);
}

TString THandlerSessionCreate::ChangeSameSiteFieldInSessionCookie(const TString& cookie) {
Expand Down
5 changes: 3 additions & 2 deletions ydb/mvp/oidc_proxy/oidc_session_create.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@ class THandlerSessionCreate : public NActors::TActorBootstrapped<THandlerSession
const TOpenIdConnectSettings& settings);

virtual void RequestSessionToken(const TString&) = 0;
virtual void ProcessSessionToken(const TString& accessToken, const NActors::TActorContext&) = 0;
virtual void ProcessSessionToken(const NJson::TJsonValue& jsonValue) = 0;

void Bootstrap();
void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx);
void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event);

protected:
TString ChangeSameSiteFieldInSessionCookie(const TString& cookie);
void RetryRequestToProtectedResourceAndDie();
void RetryRequestToProtectedResourceAndDie(NHttp::THeadersBuilder* responseHeaders);
void ReplyAndPassAway(NHttp::THttpOutgoingResponsePtr httpResponse);
void ReplyBadRequestAndPassAway(TString errorMessage);

private:
void SendUnknownErrorResponseAndDie();
Expand Down
21 changes: 19 additions & 2 deletions ydb/mvp/oidc_proxy/oidc_session_create_nebius.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,31 @@ void THandlerSessionCreateNebius::RequestSessionToken(const TString& code) {
Become(&THandlerSessionCreateNebius::StateWork);
}

void THandlerSessionCreateNebius::ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ) {
void THandlerSessionCreateNebius::ProcessSessionToken(const NJson::TJsonValue& jsonValue) {
const NJson::TJsonValue* jsonAccessToken;
const NJson::TJsonValue* jsonExpiresIn;
TString sessionToken;
unsigned long long expiresIn;
if (!jsonValue.GetValuePointer("access_token", &jsonAccessToken)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: `access_token` not found");
}
if (!jsonAccessToken->GetString(&sessionToken)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: failed to extract `access_token`");
}
if (!jsonValue.GetValuePointer("expires_in", &jsonExpiresIn)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: `expires_in` not found");
}
if (!jsonExpiresIn->GetUInteger(&expiresIn)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: failed to extract `expires_in`");
}
expiresIn = std::min(expiresIn, static_cast<unsigned long long>(TDuration::Days(7).Seconds())); // clean cookies no less than once a week.
TString sessionCookieName = CreateNameSessionCookie(Settings.ClientId);
TString sessionCookieValue = Base64Encode(sessionToken);
BLOG_D("Set session cookie: (" << sessionCookieName << ": " << NKikimr::MaskTicket(sessionCookieValue) << ")");

NHttp::THeadersBuilder responseHeaders;
SetCORS(Request, &responseHeaders);
responseHeaders.Set("Set-Cookie", CreateSecureCookie(sessionCookieName, sessionCookieValue));
responseHeaders.Set("Set-Cookie", CreateSecureCookie(sessionCookieName, sessionCookieValue, expiresIn));
responseHeaders.Set("Location", Context.GetRequestedAddress());
ReplyAndPassAway(Request->CreateResponse("302", "Cookie set", responseHeaders));
}
Expand Down
4 changes: 2 additions & 2 deletions ydb/mvp/oidc_proxy/oidc_session_create_nebius.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ class THandlerSessionCreateNebius : public THandlerSessionCreate {
const TOpenIdConnectSettings& settings);

void RequestSessionToken(const TString& code) override;
void ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) override;
void ProcessSessionToken(const NJson::TJsonValue& jsonValue) override;

private:
STFUNC(StateWork) {
switch (ev->GetTypeRewrite()) {
HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
}
}
};
Expand Down
13 changes: 10 additions & 3 deletions ydb/mvp/oidc_proxy/oidc_session_create_yandex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
namespace NMVP {
namespace NOIDC {

using namespace NActors;

THandlerSessionCreateYandex::THandlerSessionCreateYandex(const NActors::TActorId& sender,
const NHttp::THttpIncomingRequestPtr& request,
const NActors::TActorId& httpProxyId,
Expand All @@ -30,7 +32,12 @@ void THandlerSessionCreateYandex::RequestSessionToken(const TString& code) {
Become(&THandlerSessionCreateYandex::StateWork);
}

void THandlerSessionCreateYandex::ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) {
void THandlerSessionCreateYandex::ProcessSessionToken(const NJson::TJsonValue& jsonValue) {
const NJson::TJsonValue* jsonAccessToken, jsonExpiresIn;
if (!jsonValue.GetValuePointer("access_token", &jsonAccessToken)) {
return ReplyBadRequestAndPassAway("Wrong OIDC provider response: access_token not found");
}
TString sessionToken = jsonAccessToken->GetStringRobust();
std::unique_ptr<NYdbGrpc::TServiceConnection<TSessionService>> connection = CreateGRpcServiceConnection<TSessionService>(Settings.SessionServiceEndpoint);

yandex::cloud::priv::oauth::v1::CreateSessionRequest requestCreate;
Expand All @@ -45,8 +52,8 @@ void THandlerSessionCreateYandex::ProcessSessionToken(const TString& sessionToke
SetHeader(meta, "authorization", token);
meta.Timeout = TDuration::Seconds(10);

NActors::TActorSystem* actorSystem = ctx.ActorSystem();
NActors::TActorId actorId = ctx.SelfID;
NActors::TActorSystem* actorSystem = TActivationContext::ActorSystem();
NActors::TActorId actorId = SelfId();
NYdbGrpc::TResponseCallback<yandex::cloud::priv::oauth::v1::CreateSessionResponse> responseCb =
[actorId, actorSystem](NYdbGrpc::TGrpcStatus&& status, yandex::cloud::priv::oauth::v1::CreateSessionResponse&& response) -> void {
if (status.Ok()) {
Expand Down
4 changes: 2 additions & 2 deletions ydb/mvp/oidc_proxy/oidc_session_create_yandex.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ class THandlerSessionCreateYandex : public THandlerSessionCreate {
const TOpenIdConnectSettings& settings);

void RequestSessionToken(const TString& code) override;
void ProcessSessionToken(const TString& sessionToken, const NActors::TActorContext& ctx) override;
void ProcessSessionToken(const NJson::TJsonValue& jsonValue) override;
void HandleCreateSession(TEvPrivate::TEvCreateSessionResponse::TPtr event);
void HandleError(TEvPrivate::TEvErrorResponse::TPtr event);

private:
STFUNC(StateWork) {
switch (ev->GetTypeRewrite()) {
HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
hFunc(TEvPrivate::TEvCreateSessionResponse, HandleCreateSession);
hFunc(TEvPrivate::TEvErrorResponse, HandleError);
}
Expand Down
5 changes: 3 additions & 2 deletions ydb/mvp/oidc_proxy/openid_connect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,11 @@ const TString& GetAuthCallbackUrl() {
return callbackUrl;
}

TString CreateSecureCookie(const TString& name, const TString& value) {
TString CreateSecureCookie(const TString& name, const TString& value, const ui32 expiredSeconds) {
TStringBuilder cookieBuilder;
cookieBuilder << name << "=" << value
<< "; Path=/; Secure; HttpOnly; SameSite=None; Partitioned";
<< "; Path=/; Secure; HttpOnly; SameSite=None; Partitioned"
<< "; Max-Age=" << expiredSeconds;
return cookieBuilder;
}

Expand Down
2 changes: 1 addition & 1 deletion ydb/mvp/oidc_proxy/openid_connect.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ 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 CreateSecureCookie(const TString& name, const TString& value, const ui32 expiredSeconds);
TString ClearSecureCookie(const TString& name);
void SetCORS(const NHttp::THttpIncomingRequestPtr& request, NHttp::THeadersBuilder* const headers);
TRestoreOidcContextResult RestoreOidcContext(const NHttp::TCookies& cookies, const TString& key);
Expand Down
Loading