diff --git a/deps/rabbitmq_management/include/rabbit_mgmt.hrl b/deps/rabbitmq_management/include/rabbit_mgmt.hrl index 6c64635747..0067551865 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 5ecef61c3a..22b3aeff96 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 521345a773..e74d653043 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,14 @@ init(Req0, State) -> bootstrap_oauth(Req0, State) -> AuthSettings = rabbit_mgmt_wm_auth:authSettings(), Dependencies = oauth_dependencies(), + {Req1, SetTokenAuth} = set_token_auth(AuthSettings, Req0), JSContent = import_dependencies(Dependencies) ++ set_oauth_settings(AuthSettings) ++ - set_token_auth(AuthSettings, Req0) ++ + SetTokenAuth ++ export_dependencies(Dependencies), + {ok, cowboy_req:reply(200, #{<<"content-type">> => <<"text/javascript; charset=utf-8">>}, - JSContent, Req0), State}. + JSContent, Req1), State}. set_oauth_settings(AuthSettings) -> JsonAuthSettings = rabbit_json:encode(rabbit_mgmt_format:format_nulls(AuthSettings)), @@ -33,11 +36,35 @@ 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; - false -> - [] + false -> { + Req0, + [] + } end. import_dependencies(Dependencies) -> diff --git a/selenium/bin/components/fakeportal b/selenium/bin/components/fakeportal index cd42c272fe..b0693b85a3 100644 --- a/selenium/bin/components/fakeportal +++ b/selenium/bin/components/fakeportal @@ -52,7 +52,7 @@ start_fakeportal() { --env CLIENT_ID="${CLIENT_ID}" \ --env CLIENT_SECRET="${CLIENT_SECRET}" \ --env NODE_EXTRA_CA_CERTS=/etc/uaa/ca_uaa_certificate.pem \ - -v ${TEST_CONFIG_PATH}/uaa:/etc/uaa \ + -v ${TEST_CONFIG_DIR}/uaa:/etc/uaa \ -v ${FAKEPORTAL_DIR}:/code/fakeportal \ mocha-test:${mocha_test_tag} run fakeportal