Skip to content

Commit 3946c78

Browse files
authored
OIDC: Add support redirects (#8151)
1 parent 88a86d9 commit 3946c78

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

ydb/mvp/oidc_proxy/oidc_protected_page.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,12 @@ class THandlerSessionServiceCheck : public NActors::TActorBootstrapped<THandlerS
192192
request->Set("Accept-Encoding", "deflate");
193193
}
194194

195-
static NHttp::THeadersBuilder GetResponseHeaders(const NHttp::THttpIncomingResponsePtr& response) {
195+
private:
196+
NHttp::THeadersBuilder GetResponseHeaders(const NHttp::THttpIncomingResponsePtr& response) {
196197
static const TVector<TStringBuf> HEADERS_WHITE_LIST = {
197198
"Content-Type",
198199
"Connection",
199200
"X-Worker-Name",
200-
"Location",
201201
"Set-Cookie",
202202
"Access-Control-Allow-Origin",
203203
"Access-Control-Allow-Credentials",
@@ -211,16 +211,25 @@ class THandlerSessionServiceCheck : public NActors::TActorBootstrapped<THandlerS
211211
resultHeaders.Set(header, headers.Get(header));
212212
}
213213
}
214+
static const TString LOCATION_HEADER_NAME = "Location";
215+
if (headers.Has(LOCATION_HEADER_NAME)) {
216+
resultHeaders.Set(LOCATION_HEADER_NAME, GetFixedLocationHeader(headers.Get(LOCATION_HEADER_NAME)));
217+
}
214218
return resultHeaders;
215219
}
216220

217-
private:
218221
void SendSecureHttpRequest(const NHttp::THttpIncomingResponsePtr& response, const NActors::TActorContext& ctx) {
219222
NHttp::THttpOutgoingRequestPtr request = response->GetRequest();
220223
LOG_DEBUG_S(ctx, EService::MVP, "Try to send request to HTTPS port");
221224
NHttp::THeadersBuilder headers {request->Headers};
222225
ForwardUserRequest(headers.Get(AUTH_HEADER_NAME), ctx, true);
223226
}
227+
228+
TString GetFixedLocationHeader(TStringBuf location) {
229+
TStringBuf scheme, host, uri;
230+
NHttp::CrackURL(ProtectedPageUrl, scheme, host, uri);
231+
return TStringBuilder() << '/' << host << location;
232+
}
224233
};
225234

226235
} // NMVP

ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,54 @@ Y_UNIT_TEST_SUITE(Mvp) {
253253
}
254254

255255

256+
Y_UNIT_TEST(OpenIdConnectFixLocationHeader) {
257+
TPortManager tp;
258+
ui16 sessionServicePort = tp.GetPort(8655);
259+
TMvpTestRuntime runtime;
260+
runtime.Initialize();
261+
262+
const TString allowedProxyHost {"ydb.viewer.page:1234"};
263+
264+
TOpenIdConnectSettings settings {
265+
.SessionServiceEndpoint = "localhost:" + ToString(sessionServicePort),
266+
.AllowedProxyHosts = {allowedProxyHost},
267+
.AccessServiceType = NMvp::yandex_v2
268+
};
269+
270+
const NActors::TActorId edge = runtime.AllocateEdgeActor();
271+
const NActors::TActorId target = runtime.Register(new NMVP::TProtectedPageHandler(edge, settings));
272+
273+
TSessionServiceMock sessionServiceMock;
274+
sessionServiceMock.AllowedCookies.second = "allowed_session_cookie";
275+
grpc::ServerBuilder builder;
276+
builder.AddListeningPort(settings.SessionServiceEndpoint, grpc::InsecureServerCredentials()).RegisterService(&sessionServiceMock);
277+
std::unique_ptr<grpc::Server> sessionServer(builder.BuildAndStart());
278+
279+
NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest();
280+
EatWholeString(incomingRequest, "GET /" + allowedProxyHost + "/counters HTTP/1.1\r\n"
281+
"Host: oidcproxy.net\r\n"
282+
"Cookie: yc_session=allowed_session_cookie\r\n\r\n");
283+
runtime.Send(new IEventHandle(target, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest)));
284+
TAutoPtr<IEventHandle> handle;
285+
286+
auto outgoingRequestEv = runtime.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpOutgoingRequest>(handle);
287+
UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->Host, allowedProxyHost);
288+
UNIT_ASSERT_STRINGS_EQUAL(outgoingRequestEv->Request->URL, "/counters");
289+
UNIT_ASSERT_STRING_CONTAINS(outgoingRequestEv->Request->Headers, "Authorization: Bearer protected_page_iam_token");
290+
UNIT_ASSERT_EQUAL(outgoingRequestEv->Request->Secure, false);
291+
NHttp::THttpIncomingResponsePtr incomingResponse = new NHttp::THttpIncomingResponse(outgoingRequestEv->Request);
292+
EatWholeString(incomingResponse, "HTTP/1.1 307 Temporary Redirect\r\n"
293+
"Connection: close\r\n"
294+
"Location: /node/12345/counters\r\n"
295+
"Content-Length:0\r\n\r\n");
296+
runtime.Send(new IEventHandle(handle->Sender, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(outgoingRequestEv->Request, incomingResponse)));
297+
298+
auto outgoingResponseEv = runtime.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpOutgoingResponse>(handle);
299+
UNIT_ASSERT_STRINGS_EQUAL(outgoingResponseEv->Response->Status, "307");
300+
UNIT_ASSERT_STRING_CONTAINS(outgoingResponseEv->Response->Headers, "Location: /" + allowedProxyHost + "/node/12345/counters");
301+
}
302+
303+
256304
Y_UNIT_TEST(OpenIdConnectExchangeNebius) {
257305
TPortManager tp;
258306
ui16 sessionServicePort = tp.GetPort(8655);

0 commit comments

Comments
 (0)