From 1c71922224b67c3bad4e5e15e1a682bf1f3cd957 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 12 Mar 2025 16:47:33 +0100 Subject: [PATCH 1/2] Use POST+Redirect_with_cookie (cherry picked from commit 69b54869c9b001e54a2ba836a452ff3026a5170e) (cherry picked from commit 5e5521a3c0785c4cd45ecee336b2a9c39e858bab) # Conflicts: # deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl --- .../include/rabbit_mgmt.hrl | 3 + .../src/rabbit_mgmt_login.erl | 57 +++++++++++++------ .../src/rabbit_mgmt_oauth_bootstrap.erl | 45 ++++++++++++++- 3 files changed, 86 insertions(+), 19 deletions(-) diff --git a/deps/rabbitmq_management/include/rabbit_mgmt.hrl b/deps/rabbitmq_management/include/rabbit_mgmt.hrl index 6c64635747af..006755186563 100644 --- a/deps/rabbitmq_management/include/rabbit_mgmt.hrl +++ b/deps/rabbitmq_management/include/rabbit_mgmt.hrl @@ -13,3 +13,6 @@ -define(MANAGEMENT_PG_GROUP, management_db). -define(MANAGEMENT_DEFAULT_HTTP_MAX_BODY_SIZE, 20000000). + +-define(OAUTH2_ACCESS_TOKEN_COOKIE_NAME, <<"access_token">>). +-define(OAUTH2_ACCESS_TOKEN_COOKIE_PATH, <<"/js/oidc-oauth/bootstrap.js">>). diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_login.erl b/deps/rabbitmq_management/src/rabbit_mgmt_login.erl index 5ecef61c3a58..22b3aeff9631 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_login.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_login.erl @@ -10,29 +10,52 @@ -export([init/2]). -include_lib("rabbitmq_management_agent/include/rabbit_mgmt_records.hrl"). +-include("rabbit_mgmt.hrl"). + %%-------------------------------------------------------------------- init(Req0, State) -> login(cowboy_req:method(Req0), Req0, State). -login(<<"POST">>, Req0, State) -> - {ok, Body, _} = cowboy_req:read_urlencoded_body(Req0), - AccessToken = proplists:get_value(<<"access_token">>, Body), - case rabbit_mgmt_util:is_authorized_user(Req0, #context{}, <<"">>, AccessToken, false) of - {true, Req1, _} -> - NewBody = [""], - Req2 = cowboy_req:reply(200, #{<<"content-type">> => <<"text/html; charset=utf-8">>}, NewBody, Req1), - {ok, Req2, State}; - {false, ReqData1, Reason} -> - Home = cowboy_req:uri(ReqData1, #{path => rabbit_mgmt_util:get_path_prefix() ++ "/", qs => "error=" ++ Reason}), - ReqData2 = cowboy_req:reply(302, - #{<<"Location">> => iolist_to_binary(Home) }, - <<>>, ReqData1), - {ok, ReqData2, State} - end; +login(<<"POST">>, Req0=#{scheme := Scheme}, State) -> + {ok, Body, _} = cowboy_req:read_urlencoded_body(Req0), + AccessToken = proplists:get_value(<<"access_token">>, Body), + case rabbit_mgmt_util:is_authorized_user(Req0, #context{}, <<"">>, AccessToken, false) of + {true, Req1, _} -> + CookieSettings = #{ + http_only => true, + path => ?OAUTH2_ACCESS_TOKEN_COOKIE_PATH, + max_age => 30, + same_site => strict + }, + SetCookie = cowboy_req:set_resp_cookie(?OAUTH2_ACCESS_TOKEN_COOKIE_NAME, AccessToken, Req1, + case Scheme of + <<"https">> -> CookieSettings#{ secure => true}; + _ -> CookieSettings + end), + Home = cowboy_req:uri(SetCookie, #{ + path => rabbit_mgmt_util:get_path_prefix() ++ "/" + }), + Redirect = cowboy_req:reply(302, #{ + <<"Location">> => iolist_to_binary(Home) + }, <<>>, SetCookie), + {ok, Redirect, State}; + {false, ReqData1, Reason} -> + replyWithError(Reason, ReqData1, State) + end; login(_, Req0, State) -> %% Method not allowed. {ok, cowboy_req:reply(405, Req0), State}. + +replyWithError(Reason, Req, State) -> + Home = cowboy_req:uri(Req, #{ + path => rabbit_mgmt_util:get_path_prefix() ++ "/", + qs => "error=" ++ Reason + }), + Req2 = cowboy_req:reply(302, #{ + <<"Location">> => iolist_to_binary(Home) + }, <<>>, Req), + {ok, Req2, State}. + + diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl b/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl index 32c3cf9503c5..20593cc8c134 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl @@ -8,6 +8,7 @@ -module(rabbit_mgmt_oauth_bootstrap). -export([init/2]). +-include("rabbit_mgmt.hrl"). %%-------------------------------------------------------------------- @@ -18,12 +19,23 @@ init(Req0, State) -> bootstrap_oauth(Req0, State) -> AuthSettings = rabbit_mgmt_wm_auth:authSettings(), Dependencies = oauth_dependencies(), +<<<<<<< HEAD JSContent = import_dependencies(Dependencies) ++ set_oauth_settings(AuthSettings) ++ set_token_auth(AuthSettings, Req0) ++ export_dependencies(Dependencies), {ok, cowboy_req:reply(200, #{<<"content-type">> => <<"text/javascript; charset=utf-8">>}, JSContent, Req0), State}. +======= + {Req1, SetTokenAuth} = set_token_auth(AuthSettings, Req0), + JSContent = import_dependencies(Dependencies) ++ + set_oauth_settings(AuthSettings) ++ + SetTokenAuth ++ + export_dependencies(Dependencies), + + {ok, cowboy_req:reply(200, #{<<"content-type">> => <<"text/javascript; charset=utf-8">>}, + JSContent, Req1), State}. +>>>>>>> 5e5521a3c (Use POST+Redirect_with_cookie) set_oauth_settings(AuthSettings) -> JsonAuthSettings = rabbit_json:encode(rabbit_mgmt_format:format_nulls(AuthSettings)), @@ -33,11 +45,40 @@ set_token_auth(AuthSettings, Req0) -> case proplists:get_value(oauth_enabled, AuthSettings, false) of true -> case cowboy_req:parse_header(<<"authorization">>, Req0) of - {bearer, Token} -> ["set_token_auth('", Token, "');"]; - _ -> [] + {bearer, Token} -> + { + Req0, + ["set_token_auth('", Token, "');"] + }; + _ -> + Cookies = cowboy_req:parse_cookies(Req0), + case lists:keyfind(?OAUTH2_ACCESS_TOKEN_COOKIE_NAME, 1, Cookies) of + {_, Token} -> + { + cowboy_req:set_resp_cookie( + ?OAUTH2_ACCESS_TOKEN_COOKIE_NAME, <<"">>, Req0, #{ + max_age => 0, + http_only => true, + path => ?OAUTH2_ACCESS_TOKEN_COOKIE_PATH, + same_site => strict + }), + ["set_token_auth('", Token, "');"] + }; + false -> { + Req0, + [] + } + end end; +<<<<<<< HEAD false -> [] +======= + false -> { + Req0, + [] + } +>>>>>>> 5e5521a3c (Use POST+Redirect_with_cookie) end. import_dependencies(Dependencies) -> From 02e5b07771f39eab0fbb44984f9ba77e47202dcb Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Wed, 12 Mar 2025 16:14:06 -0400 Subject: [PATCH 2/2] Resolve conflicts #13507 #13476 #13502 --- .../src/rabbit_mgmt_oauth_bootstrap.erl | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl b/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl index 20593cc8c134..7debdf569028 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl @@ -19,23 +19,14 @@ init(Req0, State) -> bootstrap_oauth(Req0, State) -> AuthSettings = rabbit_mgmt_wm_auth:authSettings(), Dependencies = oauth_dependencies(), -<<<<<<< HEAD - JSContent = import_dependencies(Dependencies) ++ - set_oauth_settings(AuthSettings) ++ - set_token_auth(AuthSettings, Req0) ++ - export_dependencies(Dependencies), - {ok, cowboy_req:reply(200, #{<<"content-type">> => <<"text/javascript; charset=utf-8">>}, - JSContent, Req0), State}. -======= {Req1, SetTokenAuth} = set_token_auth(AuthSettings, Req0), JSContent = import_dependencies(Dependencies) ++ set_oauth_settings(AuthSettings) ++ SetTokenAuth ++ export_dependencies(Dependencies), - + {ok, cowboy_req:reply(200, #{<<"content-type">> => <<"text/javascript; charset=utf-8">>}, JSContent, Req1), State}. ->>>>>>> 5e5521a3c (Use POST+Redirect_with_cookie) set_oauth_settings(AuthSettings) -> JsonAuthSettings = rabbit_json:encode(rabbit_mgmt_format:format_nulls(AuthSettings)), @@ -45,15 +36,15 @@ set_token_auth(AuthSettings, Req0) -> case proplists:get_value(oauth_enabled, AuthSettings, false) of true -> case cowboy_req:parse_header(<<"authorization">>, Req0) of - {bearer, Token} -> + {bearer, Token} -> { - Req0, + Req0, ["set_token_auth('", Token, "');"] }; - _ -> + _ -> Cookies = cowboy_req:parse_cookies(Req0), - case lists:keyfind(?OAUTH2_ACCESS_TOKEN_COOKIE_NAME, 1, Cookies) of - {_, Token} -> + case lists:keyfind(?OAUTH2_ACCESS_TOKEN_COOKIE_NAME, 1, Cookies) of + {_, Token} -> { cowboy_req:set_resp_cookie( ?OAUTH2_ACCESS_TOKEN_COOKIE_NAME, <<"">>, Req0, #{ @@ -61,24 +52,19 @@ set_token_auth(AuthSettings, Req0) -> http_only => true, path => ?OAUTH2_ACCESS_TOKEN_COOKIE_PATH, same_site => strict - }), + }), ["set_token_auth('", Token, "');"] }; false -> { - Req0, + Req0, [] } end end; -<<<<<<< HEAD - false -> - [] -======= false -> { - Req0, + Req0, [] } ->>>>>>> 5e5521a3c (Use POST+Redirect_with_cookie) end. import_dependencies(Dependencies) ->