Skip to content

Commit bf1a83a

Browse files
authored
[oidc proxy] Create only one ydb_oidc_cookie (#9588)
1 parent 8ca1840 commit bf1a83a

10 files changed

+339
-196
lines changed

ydb/mvp/oidc_proxy/context.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44
#include <library/cpp/string_utils/base64/base64.h>
55
#include <ydb/library/actors/http/http.h>
66
#include "openid_connect.h"
7+
#include "oidc_settings.h"
78
#include "context.h"
89

910
namespace NMVP {
1011
namespace NOIDC {
1112

12-
TContext::TContext(const TString& state, const TString& requestedAddress, bool isAjaxRequest)
13-
: State(state)
14-
, AjaxRequest(isAjaxRequest)
15-
, RequestedAddress(requestedAddress)
13+
TContext::TContext(const TInitializer& initializer)
14+
: State(initializer.State)
15+
, AjaxRequest(initializer.AjaxRequest)
16+
, RequestedAddress(initializer.RequestedAddress)
1617
{}
1718

1819
TContext::TContext(const NHttp::THttpIncomingRequestPtr& request)
@@ -21,8 +22,17 @@ TContext::TContext(const NHttp::THttpIncomingRequestPtr& request)
2122
, RequestedAddress(GetRequestedUrl(request, AjaxRequest))
2223
{}
2324

24-
TString TContext::GetState() const {
25-
return State;
25+
TString TContext::GetState(const TString& key) const {
26+
static const TDuration STATE_LIFE_TIME = TDuration::Minutes(10);
27+
TInstant expirationTime = TInstant::Now() + STATE_LIFE_TIME;
28+
TStringBuilder json;
29+
json << "{\"state\":\"" << State
30+
<< "\",\"expiration_time\":\"" << ToString(expirationTime.TimeT()) << "\"}";
31+
TString digest = HmacSHA1(key, json);
32+
TStringBuilder signedState;
33+
signedState << "{\"container\":\"" << Base64Encode(json) << "\","
34+
"\"digest\":\"" << Base64Encode(digest) << "\"}";
35+
return Base64EncodeNoPadding(signedState);
2636
}
2737

2838
bool TContext::IsAjaxRequest() const {
@@ -34,25 +44,22 @@ TString TContext::GetRequestedAddress() const {
3444
}
3545

3646
TString TContext::CreateYdbOidcCookie(const TString& secret) const {
37-
static constexpr size_t COOKIE_MAX_AGE_SEC = 420;
38-
return TStringBuilder() << CreateNameYdbOidcCookie(secret, State) << "="
47+
static constexpr size_t COOKIE_MAX_AGE_SEC = 3600;
48+
return TStringBuilder() << TOpenIdConnectSettings::YDB_OIDC_COOKIE << "="
3949
<< GenerateCookie(secret) << ";"
4050
" Path=" << GetAuthCallbackUrl() << ";"
4151
" Max-Age=" << COOKIE_MAX_AGE_SEC << ";"
4252
" SameSite=None; Secure";
4353
}
4454

45-
TString TContext::GenerateCookie(const TString& secret) const {
46-
const TDuration StateLifeTime = TDuration::Minutes(10);
47-
TInstant expirationTime = TInstant::Now() + StateLifeTime;
48-
TStringBuilder stateStruct;
49-
stateStruct << "{\"state\":\"" << State
50-
<< "\",\"requested_address\":\"" << RequestedAddress
51-
<< "\",\"expiration_time\":" << ToString(expirationTime.TimeT())
52-
<< ",\"ajax_request\":" << (AjaxRequest ? "true" : "false") << "}";
53-
TString digest = HmacSHA256(secret, stateStruct);
54-
TString cookieStruct {"{\"state_struct\":\"" + Base64Encode(stateStruct) + "\",\"digest\":\"" + Base64Encode(digest) + "\"}"};
55-
return Base64Encode(cookieStruct);
55+
TString TContext::GenerateCookie(const TString& key) const {
56+
TStringBuilder requestedAddressContext;
57+
requestedAddressContext << "{\"requested_address\":\"" << RequestedAddress << "\"}";
58+
TString digest = HmacSHA256(key, requestedAddressContext);
59+
TStringBuilder signedRequestedAddress;
60+
signedRequestedAddress << "{\"requested_address_context\":\"" << Base64Encode(requestedAddressContext)
61+
<< "\",\"digest\":\"" << Base64Encode(digest) << "\"}";
62+
return Base64Encode(signedRequestedAddress);
5663
}
5764

5865
TString TContext::GenerateState() {

ydb/mvp/oidc_proxy/context.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,24 @@ namespace NMVP {
1414
namespace NOIDC {
1515

1616
class TContext {
17+
public:
18+
struct TInitializer {
19+
TString State;
20+
TString RequestedAddress;
21+
bool AjaxRequest = false;
22+
};
23+
1724
private:
1825
TString State;
1926
bool AjaxRequest = false;
2027
TString RequestedAddress;
2128

2229
public:
23-
TContext(const TString& state = "", const TString& requestedAddress = "", bool isAjaxRequest = false);
30+
TContext() = default;
31+
TContext(const TInitializer& initializer);
2432
TContext(const NHttp::THttpIncomingRequestPtr& request);
2533

26-
TString GetState() const;
34+
TString GetState(const TString& key) const;
2735
bool IsAjaxRequest() const;
2836
TString GetRequestedAddress() const;
2937

@@ -34,7 +42,7 @@ class TContext {
3442
static bool DetectAjaxRequest(const NHttp::THttpIncomingRequestPtr& request);
3543
static TStringBuf GetRequestedUrl(const NHttp::THttpIncomingRequestPtr& request, bool isAjaxRequest);
3644

37-
TString GenerateCookie(const TString& secret) const;
45+
TString GenerateCookie(const TString& key) const;
3846
};
3947

4048
} // NOIDC

ydb/mvp/oidc_proxy/oidc_protected_page_nebius.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ void THandlerSessionServiceCheckNebius::ExchangeSessionToken(const TString sessi
100100

101101
void THandlerSessionServiceCheckNebius::RequestAuthorizationCode(const NActors::TActorContext& ctx) {
102102
LOG_DEBUG_S(ctx, EService::MVP, "Request authorization code");
103-
TContext context(Request);
104-
NHttp::THttpOutgoingResponsePtr httpResponse = GetHttpOutgoingResponsePtr(Request, Settings, context);
103+
NHttp::THttpOutgoingResponsePtr httpResponse = GetHttpOutgoingResponsePtr(Request, Settings);
105104
ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse));
106105
Die(ctx);
107106
}

ydb/mvp/oidc_proxy/oidc_protected_page_yandex.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ void THandlerSessionServiceCheckYandex::Handle(TEvPrivate::TEvErrorResponse::TPt
3232
LOG_DEBUG_S(ctx, EService::MVP, "SessionService.Check(): " << event->Get()->Status);
3333
NHttp::THttpOutgoingResponsePtr httpResponse;
3434
if (event->Get()->Status == "400") {
35-
TContext context(Request);
36-
httpResponse = GetHttpOutgoingResponsePtr(Request, Settings, context);
35+
httpResponse = GetHttpOutgoingResponsePtr(Request, Settings);
3736
} else {
3837
httpResponse = Request->CreateResponse( event->Get()->Status, event->Get()->Message, "text/plain", event->Get()->Details);
3938
}

0 commit comments

Comments
 (0)