Skip to content

Commit e57c9f0

Browse files
oidc_proxy_return_401
1 parent 7156a4e commit e57c9f0

File tree

3 files changed

+89
-6
lines changed

3 files changed

+89
-6
lines changed

ydb/mvp/oidc_proxy/oidc_proxy_ut.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,86 @@ Y_UNIT_TEST_SUITE(Mvp) {
467467
OidcFullAuthorizationFlow(redirectStrategy);
468468
}
469469

470+
void OidcWrongStateAuthorizationFlow(TRedirectStrategyBase& redirectStrategy) {
471+
TPortManager tp;
472+
ui16 sessionServicePort = tp.GetPort(8655);
473+
TMvpTestRuntime runtime;
474+
runtime.Initialize();
475+
476+
const TString allowedProxyHost {"ydb.viewer.page"};
477+
478+
TOpenIdConnectSettings settings {
479+
.SessionServiceEndpoint = "localhost:" + ToString(sessionServicePort),
480+
.AuthorizationServerAddress = "https://auth.cloud.yandex.ru",
481+
.ClientSecret = "0123456789abcdef",
482+
.AllowedProxyHosts = {allowedProxyHost}
483+
};
484+
485+
const NActors::TActorId edge = runtime.AllocateEdgeActor();
486+
const NActors::TActorId target = runtime.Register(new NMVP::TProtectedPageHandler(edge, settings));
487+
488+
TSessionServiceMock sessionServiceMock;
489+
sessionServiceMock.AllowedCookies.second = "allowed_session_cookie";
490+
sessionServiceMock.AllowedAccessTokens.insert("access_token_value");
491+
grpc::ServerBuilder builder;
492+
builder.AddListeningPort(settings.SessionServiceEndpoint, grpc::InsecureServerCredentials()).RegisterService(&sessionServiceMock);
493+
std::unique_ptr<grpc::Server> sessionServer(builder.BuildAndStart());
494+
495+
NHttp::THttpIncomingRequestPtr incomingRequest = new NHttp::THttpIncomingRequest();
496+
incomingRequest->Endpoint->Secure = true;
497+
498+
const TString hostProxy = "oidcproxy.yandex.net";
499+
const TString protectedPage = "/" + allowedProxyHost + "/counters";
500+
501+
EatWholeString(incomingRequest, redirectStrategy.CreateRequest("GET " + protectedPage + " HTTP/1.1\r\n"
502+
"Host: " + hostProxy + "\r\n"
503+
"Cookie: yc_session=invalid_cookie\r\n"
504+
"Referer: https://" + hostProxy + protectedPage + "\r\n"));
505+
runtime.Send(new IEventHandle(target, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest)));
506+
507+
TAutoPtr<IEventHandle> handle;
508+
NHttp::TEvHttpProxy::TEvHttpOutgoingResponse* outgoingResponseEv = runtime.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpOutgoingResponse>(handle);
509+
redirectStrategy.CheckRedirectStatus(outgoingResponseEv);
510+
TString location = redirectStrategy.GetRedirectUrl(outgoingResponseEv);
511+
UNIT_ASSERT_STRING_CONTAINS(location, "https://auth.cloud.yandex.ru/oauth/authorize");
512+
UNIT_ASSERT_STRING_CONTAINS(location, "response_type=code");
513+
UNIT_ASSERT_STRING_CONTAINS(location, "scope=openid");
514+
UNIT_ASSERT_STRING_CONTAINS(location, "client_id=" + TOpenIdConnectSettings::CLIENT_ID);
515+
UNIT_ASSERT_STRING_CONTAINS(location, "redirect_uri=https://" + hostProxy + "/auth/callback");
516+
517+
NHttp::TUrlParameters urlParameters(location);
518+
const TString state = urlParameters["state"];
519+
Cerr << "iiiiiiiii state " << state << Endl;
520+
521+
const NHttp::THeaders headers(outgoingResponseEv->Response->Headers);
522+
UNIT_ASSERT(headers.Has("Set-Cookie"));
523+
TStringBuf setCookie = headers.Get("Set-Cookie");
524+
UNIT_ASSERT_STRING_CONTAINS(setCookie, CreateNameYdbOidcCookie(settings.ClientSecret, state));
525+
redirectStrategy.CheckSpecificHeaders(headers);
526+
527+
const NActors::TActorId sessionCreator = runtime.Register(new NMVP::TSessionCreator(edge, settings));
528+
incomingRequest = new NHttp::THttpIncomingRequest();
529+
TStringBuilder request;
530+
request << "GET /auth/callback?code=code_template&state=" << "wrong_state" << " HTTP/1.1\r\n";
531+
request << "Host: " + hostProxy + "\r\n";
532+
request << "Cookie: " << setCookie.NextTok(";") << "\r\n";
533+
EatWholeString(incomingRequest, redirectStrategy.CreateRequest(request));
534+
runtime.Send(new IEventHandle(sessionCreator, edge, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(incomingRequest)));
535+
536+
outgoingResponseEv = runtime.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpOutgoingResponse>(handle);
537+
redirectStrategy.CheckRedirectStatus(outgoingResponseEv);
538+
}
539+
540+
Y_UNIT_TEST(OpenIdConnectotWrongStateAuthorizationFlow) {
541+
TRedirectStrategy redirectStrategy;
542+
OidcWrongStateAuthorizationFlow(redirectStrategy);
543+
}
544+
545+
Y_UNIT_TEST(OpenIdConnectotWrongStateAuthorizationFlowAjax) {
546+
TAjaxRedirectStrategy redirectStrategy;
547+
OidcWrongStateAuthorizationFlow(redirectStrategy);
548+
}
549+
470550
Y_UNIT_TEST(OpenIdConnectSessionServiceCreateAuthorizationFail) {
471551
TPortManager tp;
472552
ui16 sessionServicePort = tp.GetPort(8655);

ydb/mvp/oidc_proxy/oidc_session_create.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ class THandlerSessionCreate : public NActors::TActorBootstrapped<THandlerSession
151151
httpRequest->Set<&NHttp::THttpRequest::Body>(body);
152152
ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest));
153153
} else {
154-
ResponseHeaders.Set("Content-Type", "text/plain");
155-
NHttp::THttpOutgoingResponsePtr response = Request->CreateResponse("400", "Bad Request", ResponseHeaders, "Parameters state and code are invalid");
154+
NHttp::THttpOutgoingResponsePtr response = GetHttpOutgoingResponsePtr(TStringBuf(), Request, Settings, ResponseHeaders, IsAjaxRequest);
156155
ctx.Send(Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
157156
TBase::Die(ctx);
158157
return;

ydb/mvp/oidc_proxy/openid_connect.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ TString CreateRedirectUrl(const TRedirectUrlParameters& parameters) {
3030
TStringBuilder locationHeaderValue;
3131
TStringBuf authUrl = "/oauth/authorize";
3232
const auto& eventDetails = parameters.SessionServerCheckDetails;
33-
size_t posAuthUrl = eventDetails.find(authUrl);
34-
if (posAuthUrl != TStringBuf::npos) {
35-
size_t pos = eventDetails.rfind("https://", posAuthUrl);
36-
locationHeaderValue << eventDetails.substr(pos, posAuthUrl - pos);
33+
if (eventDetails) {
34+
size_t posAuthUrl = eventDetails.find(authUrl);
35+
if (posAuthUrl != TStringBuf::npos) {
36+
size_t pos = eventDetails.rfind("https://", posAuthUrl);
37+
locationHeaderValue << eventDetails.substr(pos, posAuthUrl - pos);
38+
} else {
39+
locationHeaderValue << parameters.OidcSettings.AuthorizationServerAddress;
40+
}
3741
} else {
3842
locationHeaderValue << parameters.OidcSettings.AuthorizationServerAddress;
3943
}

0 commit comments

Comments
 (0)