Merge pull request #13344 from rabbitmq/issue-12545

Redirect to end_session_endpoint for idp_initiated logon when it is configured
This commit is contained in:
Michael Klishin 2025-03-27 20:32:20 -04:00 committed by GitHub
commit bde9868c1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 376 additions and 67 deletions

View File

@ -154,9 +154,9 @@ export function oidc_settings_from(resource_server) {
automaticSilentRenew: true,
revokeAccessTokenOnSignout: true
}
if (resource_server.end_session_endpoint != "") {
if (resource_server.oauth_end_session_endpoint != "") {
oidcSettings.metadataSeed = {
end_session_endpoint: resource_server.end_session_endpoint
end_session_endpoint: resource_server.oauth_end_session_endpoint
}
}
if (resource_server.oauth_client_secret != "") {
@ -214,6 +214,9 @@ export function oauth_initialize(authSettings) {
if (resource_server) {
oauth.sp_initiated = resource_server.sp_initiated
oauth.authority = resource_server.oauth_provider_url
if (resource_server.oauth_end_session_endpoint != "") {
oauth.oauth_end_session_endpoint = resource_server.oauth_end_session_endpoint
}
if (!resource_server.sp_initiated) return oauth;
else oauth_initialize_user_manager(resource_server)
}
@ -311,7 +314,11 @@ export function oauth_initiateLogout() {
})
} else {
go_to_authority()
if (oauth.oauth_end_session_endpoint != null) {
location.href = oauth.oauth_end_session_endpoint
}else {
go_to_authority()
}
}
}

View File

@ -72,7 +72,7 @@ oauth_provider_to_map(OAuthProvider) ->
end,
case OAuthProvider#oauth_provider.end_session_endpoint of
undefined -> Map0;
V -> maps:put(end_session_endpoint, V, Map0)
V -> maps:put(oauth_end_session_endpoint, V, Map0)
end.
skip_unknown_mgt_resource_servers(ManagementProps, OAuth2Resources) ->

View File

@ -788,31 +788,31 @@ should_return_oauth_client_id_z(Config) ->
should_not_return_end_session_endpoint(Config) ->
assert_attribute_not_defined_for_oauth_resource_server(authSettings(),
Config, rabbit, end_session_endpoint).
Config, rabbit, oauth_end_session_endpoint).
should_return_end_session_endpoint_0(Config) ->
assertEqual_on_attribute_for_oauth_resource_server(authSettings(),
Config, rabbit, end_session_endpoint, ?config(logout_url_0, Config)).
Config, rabbit, oauth_end_session_endpoint, ?config(logout_url_0, Config)).
should_return_end_session_endpoint_1(Config) ->
assertEqual_on_attribute_for_oauth_resource_server(authSettings(),
Config, rabbit, end_session_endpoint, ?config(logout_url_1, Config)).
Config, rabbit, oauth_end_session_endpoint, ?config(logout_url_1, Config)).
should_return_oauth_resource_server_a_without_end_session_endpoint(Config) ->
assert_attribute_not_defined_for_oauth_resource_server(authSettings(),
Config, a, end_session_endpoint).
Config, a, oauth_end_session_endpoint).
should_return_oauth_resource_server_a_with_end_session_endpoint_0(Config) ->
assertEqual_on_attribute_for_oauth_resource_server(authSettings(),
Config, a, end_session_endpoint, ?config(logout_url_0, Config)).
Config, a, oauth_end_session_endpoint, ?config(logout_url_0, Config)).
should_return_oauth_resource_server_a_with_end_session_endpoint_1(Config) ->
assertEqual_on_attribute_for_oauth_resource_server(authSettings(),
Config, a, end_session_endpoint, ?config(logout_url_1, Config)).
Config, a, oauth_end_session_endpoint, ?config(logout_url_1, Config)).
should_return_oauth_resource_server_a_with_end_session_endpoint_2(Config) ->
assertEqual_on_attribute_for_oauth_resource_server(authSettings(),
Config, a, end_session_endpoint, ?config(logout_url_2, Config)).
Config, a, oauth_end_session_endpoint, ?config(logout_url_2, Config)).
should_return_mgt_oauth_resource_rabbit_without_authorization_endpoint_params(Config) ->
assert_attribute_not_defined_for_oauth_resource_server(authSettings(),

View File

@ -15,7 +15,10 @@ ensure_fakeportal() {
}
init_fakeportal() {
FAKEPORTAL_URL=${FAKEPORTAL_URL:-http://fakeportal:3000}
FAKEPORTAL_URL=${FAKEPORTAL_URL:-https://fakeportal:3000}
FAKEPORTAL_CONFIG_PATH=${FAKEPORTAL_CONFIG_PATH:-oauth/fakeportal}
FAKEPORTAL_CONFIG_DIR=$(realpath ${TEST_DIR}/${FAKEPORTAL_CONFIG_PATH})
FAKEPORTAL_DIR=${SCRIPT}/../../fakeportal
CLIENT_ID="${CLIENT_ID:-rabbit_idp_user}"
CLIENT_SECRET="${CLIENT_SECRET:-rabbit_idp_user}"
@ -32,6 +35,9 @@ init_fakeportal() {
print "> CLIENT_ID: ${CLIENT_ID}"
print "> CLIENT_SECRET: ${CLIENT_SECRET}"
print "> RABBITMQ_URL: ${RABBITMQ_URL}"
generate-ca-server-client-kpi fakeportal $FAKEPORTAL_CONFIG_DIR
}
start_fakeportal() {
begin "Starting fakeportal ..."
@ -40,6 +46,10 @@ start_fakeportal() {
kill_container_if_exist fakeportal
mocha_test_tag=($(md5sum $SELENIUM_ROOT_FOLDER/package.json))
MOUNT_FAKEPORTAL_CONF_DIR=$CONF_DIR/fakeportal
mkdir -p $MOUNT_FAKEPORTAL_CONF_DIR
cp ${FAKEPORTAL_CONFIG_DIR}/*.pem $MOUNT_FAKEPORTAL_CONF_DIR
docker run \
--detach \
--name fakeportal \
@ -52,7 +62,8 @@ 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_DIR}/uaa:/etc/uaa \
-v ${TEST_CONFIG_PATH}/uaa:/etc/uaa \
-v ${MOUNT_FAKEPORTAL_CONF_DIR}:/etc/fakeportal \
-v ${FAKEPORTAL_DIR}:/code/fakeportal \
mocha-test:${mocha_test_tag} run fakeportal

View File

@ -0,0 +1,68 @@
#!/usr/bin/env bash
OAUTH2_PROXY_DOCKER_IMAGE=bitnami/oauth2-proxy:7.7.1
ensure_oauth2-proxy() {
if docker ps | grep oauth2-proxy &> /dev/null; then
print "oauth2-proxy already running ..."
else
start_oauth2-proxy
fi
}
init_oauth2-proxy() {
KEYCLOAK_CONFIG_PATH=${KEYCLOAK_CONFIG_PATH:-oauth/keycloak}
KEYCLOAK_CONFIG_DIR=$(realpath ${TEST_DIR}/${KEYCLOAK_CONFIG_PATH})
OAUTH2_PROXY_CONFIG_PATH=${OAUTH2_PROXY_CONFIG_PATH:-oauth/oauth2-proxy}
OAUTH2_PROXY_CONFIG_DIR=$(realpath ${TEST_DIR}/${OAUTH2_PROXY_CONFIG_PATH})
OAUTH2_PROXY_URL=${OAUTH_PROVIDER_URL}
print "> KEYCLOAK_CONFIG_DIR: ${KEYCLOAK_CONFIG_DIR}"
print "> KEYCLOAK_URL: ${KEYCLOAK_URL}"
print "> KEYCLOAK_DOCKER_IMAGE: ${KEYCLOAK_DOCKER_IMAGE}"
print "> OAUTH2_PROXY_CONFIG_DIR: ${OAUTH2_PROXY_CONFIG_DIR}"
print "> OAUTH2_PROXY_URL: ${OAUTH2_PROXY_URL}"
print "> OAUTH2_PROXY_DOCKER_IMAGE: ${OAUTH2_PROXY_DOCKER_IMAGE}"
generate-ca-server-client-kpi oauth2-proxy $OAUTH2_PROXY_CONFIG_DIR
}
start_oauth2-proxy() {
begin "Starting oauth2-proxy ..."
init_oauth2-proxy
kill_container_if_exist oauth2-proxy
MOUNT_OAUTH2_PROXY_CONF_DIR=$CONF_DIR/oauth2-proxy
MOUNT_KEYCLOAK_CONF_DIR=$CONF_DIR/keycloak
mkdir -p $MOUNT_OAUTH2_PROXY_CONF_DIR
mkdir -p $MOUNT_KEYCLOAK_CONF_DIR
${BIN_DIR}/gen-oauth2-proxy-yaml ${OAUTH2_PROXY_CONFIG_DIR} $ENV_FILE $MOUNT_OAUTH2_PROXY_CONF_DIR/alpha-config.yaml
print "> EFFECTIVE OAUTH2_PROXY_CONFIG_FILE: $MOUNT_OAUTH2_PROXY_CONF_DIR/alpha-config.yaml"
cp ${OAUTH2_PROXY_CONFIG_DIR}/*.pem $MOUNT_OAUTH2_PROXY_CONF_DIR
cp ${KEYCLOAK_CONFIG_DIR}/*.pem $MOUNT_KEYCLOAK_CONF_DIR
docker run \
--detach \
--name oauth2-proxy \
--net ${DOCKER_NETWORK} \
--publish 8442:8442 \
--env OAUTH2_PROXY_COOKIE_SECRET=${OAUTH2_PROXY_COOKIE_SECRET} \
--env OAUTH2_PROXY_EMAIL_DOMAINS="*" \
--env OAUTH2_PROXY_COOKIE_DOMAINS="" \
--env OAUTH2_PROXY_WHITELIST_DOMAINS="*" \
--env OAUTH2_PROXY_COOKIE_CSRF_PER_REQUEST="true" \
--env OAUTH2_PROXY_COOKIE_CSRF_EXPIRE="5m" \
--env OAUTH2_PROXY_REDIRECT_URL="https://oauth2-proxy:8442/oauth2/callback" \
--env OAUTH2_PROXY_TLS_KEY_FILE=/etc/oauth2-proxy/certs/server_oauth2-proxy_key.pem \
--env OAUTH2_PROXY_TLS_CERT_FILE=/etc/oauth2-proxy/certs/server_oauth2-proxy_certificate.pem \
-v ${MOUNT_KEYCLOAK_CONF_DIR}:/etc/keycloak \
-v ${MOUNT_OAUTH2_PROXY_CONF_DIR}:/etc/oauth2-proxy \
${OAUTH2_PROXY_DOCKER_IMAGE} --alpha-config /etc/oauth2-proxy/alpha-config.yaml --cookie-secure=true
wait_for_oidc_endpoint oauth2-proxy $OAUTH2_PROXY_URL $MOUNT_OAUTH2_PROXY_CONF_DIR/ca_oauth2-proxy_certificate.pem
end "oauth2-proxy is ready"
}

View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
#set -x
TEST_PATH=${1:?First parameter is the directory env and config files are relative to}
ENV_FILE=${2:?Second parameter is a comma-separated list of .env file which has exported template variables}
FINAL_CONFIG_FILE=${3:?Forth parameter is the name of the final config file. It is relative to where this script is run from}
source $ENV_FILE
parentdir="$(dirname "$FINAL_CONFIG_FILE")"
mkdir -p $parentdir
echo "" > $FINAL_CONFIG_FILE
for f in $($SCRIPT/find-template-files $TEST_PATH "alpha-config" "yaml")
do
envsubst < $f >> $FINAL_CONFIG_FILE
done

View File

@ -13,6 +13,7 @@ tabs 1
declare -i PADDING_LEVEL=0
declare -i STEP=1
declare -a REQUIRED_COMPONENTS
declare -a INIT_ONLY_COMPONENTS
find_selenium_dir() {
TEST_PATH=$1
@ -112,6 +113,7 @@ init_suite() {
begin "Initializing suite $SUITE ..."
print "> REQUIRED_COMPONENTS: ${REQUIRED_COMPONENTS[*]}"
print "> INIT_ONLY_COMPONENTS: ${INIT_ONLY_COMPONENTS[*]}"
print "> TEST_CASES_DIR: ${TEST_CASES_DIR} "
print "> TEST_CONFIG_DIR: ${TEST_CONFIG_DIR} "
print "> DOCKER_NETWORK: ${DOCKER_NETWORK} "
@ -218,20 +220,37 @@ wait_for_oidc_endpoint_docker() {
calculate_rabbitmq_url() {
echo "${RABBITMQ_SCHEME:-http}://$1${PUBLIC_RABBITMQ_PATH:-$RABBITMQ_PATH}"
}
calculate_forward_proxy_url() {
PROXIED_URL=$1
PROXY_HOSTNAME=$2
PROXY_PORT=$3
SCHEME=$(echo "$PROXIED_URL" | cut -d: -f1)
PATH=$(echo "$PROXIED_URL" | cut -d/ -f4-)
echo "$SCHEME://$PROXY_HOSTNAME:$PROXY_PORT/$PATH"
}
wait_for_url() {
BASE_URL=$1
if [[ $BASE_URL == *"localhost"** ]]; then
wait_for_url_local $BASE_URL
wait_for_url_local $@
else
wait_for_url_docker $BASE_URL
wait_for_url_docker $@
fi
}
wait_for_url_local() {
url=$1
proxy=${2:-none}
proxy_user=${3:-none}
proxy_pass=$4
curl_args="-L -f -v"
max_retry=10
counter=0
until (curl -L -f -v $url >/dev/null 2>&1)
if [[ "$proxy" != "none" && "$proxy" != "" ]]; then
curl_args="--proxy ${proxy} ${curl_args}"
fi
if [[ "$proxy_user" != "none" && "$proxy_user" != "" ]]; then
curl_args="--proxy-user ${proxy_user}:${proxy_pass} ${curl_args}"
fi
until (curl $curl_args $url >/dev/null 2>&1)
do
print "Waiting for $url to start (local)"
sleep 5
@ -244,7 +263,14 @@ wait_for_url_docker() {
url=$1
max_retry=10
counter=0
until (docker run --net ${DOCKER_NETWORK} --rm curlimages/curl:7.85.0 -L -f -v $url >/dev/null 2>&1)
curl_args="-L -f -v"
if [[ "$proxy" != "none" && "$proxy" != "" ]]; then
curl_args="--proxy ${proxy} ${curl_args}"
fi
if [[ "$proxy_user" != "none" && "$proxy_user" != "" ]]; then
curl_args="--proxy-user ${proxy_user}:${proxy_pass} ${curl_args}"
fi
until (docker run --net ${DOCKER_NETWORK} --rm curlimages/curl:7.85.0 $curl_args $url >/dev/null 2>&1)
do
print "Waiting for $url to start (docker)"
sleep 5
@ -377,7 +403,8 @@ profiles_with_local_or_docker() {
generate_env_file() {
begin "Generating env file ..."
mkdir -p $CONF_DIR
${BIN_DIR}/gen-env-file $TEST_CONFIG_DIR $ENV_FILE
${BIN_DIR}/gen-env-file $TEST_CONFIG_DIR ${ENV_FILE}.tmp
grep -v '^#' ${ENV_FILE}.tmp > $ENV_FILE
source $ENV_FILE
end "Finished generating env file."
}
@ -475,6 +502,9 @@ generate-client-keystore-if-required() {
fi
}
initOnly() {
determine_init_only_components $@
}
run() {
runWith rabbitmq
}
@ -525,6 +555,12 @@ elif [[ "$COMMAND" == "stop-rabbitmq" ]]
test_local ${BASH_REMATCH[1]}
fi
}
determine_init_only_components() {
for (( i=1; i<=$#; i++)) {
eval val='$'$i
INIT_ONLY_COMPONENTS+=( "$val" )
}
}
determine_required_components_including_rabbitmq() {
for (( i=1; i<=$#; i++)) {
eval val='$'$i
@ -560,7 +596,7 @@ run_on_docker_with() {
build_mocha_image
start_selenium
trap teardown_components EXIT
trap "teardown_components" EXIT
start_components
test
@ -637,11 +673,27 @@ ensure_components() {
start_components() {
for i in "${REQUIRED_COMPONENTS[@]}"
do
start="start_$i"
$start
local ret=$(is_init_only_component $i)
if [[ $ret == 1 ]]
then
init="init_$i"
$init
else
start="start_$i"
$start
fi
done
}
is_init_only_component() {
for i in "${INIT_ONLY_COMPONENTS[@]}"
do
if [[ $i == $1 ]]
then
return 1
fi
done
return 0
}
teardown_components() {
skip_rabbitmq=${1:-false}

View File

@ -1,5 +1,7 @@
const express = require("express");
const app = express();
const fs = require('fs');
const https = require('https');
var path = require('path');
const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest
@ -15,19 +17,38 @@ app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
app.get('/', function(req, res){
let id = default_if_blank(req.query.client_id, client_id);
let secret = default_if_blank(req.query.client_secret, client_secret);
res.render('rabbitmq', {
proxied_url: proxied_rabbitmq_url,
url: rabbitmq_url.replace(/\/?$/, '/') + "login",
name: rabbitmq_url + " for " + id,
access_token: access_token(id, secret)
});
});
let id = default_if_blank(req.query.client_id, client_id)
let secret = default_if_blank(req.query.client_secret, client_secret)
if (id == 'undefined' || secret == 'undefined') {
res.render('unauthenticated')
}else {
res.render('rabbitmq', {
proxied_url: proxied_rabbitmq_url,
url: rabbitmq_url.replace(/\/?$/, '/') + "login",
name: rabbitmq_url + " for " + id,
access_token: access_token(id, secret)
})
}
})
app.get('/favicon.ico', (req, res) => res.status(204));
app.get('/logout', function(req, res) {
const redirectUrl = uaa_url + '/logout.do?client_id=' + client_id + "&redirect=https://fakeportal:3000"
console.debug("Received /logout request -> redirect to " + redirectUrl)
res.redirect(redirectUrl);
})
https
.createServer(
{
cert: fs.readFileSync('/etc/fakeportal/server_fakeportal_certificate.pem'),
key: fs.readFileSync('/etc/fakeportal/server_fakeportal_key.pem')
},
app
)
.listen(port)
app.listen(port);
console.log('Express started on port ' + port);
function default_if_blank(value, defaultValue) {

View File

@ -0,0 +1,18 @@
<h1> FakePortal </h1>
<p>This is a portal used to test <b>Identity-Provider-based authentication</b>.
This means users comes to RabbitMQ with a token already obtained without involving RabbitMQ
management ui.
</p>
<p>This is the state of the Portal when the user is not authenticated yet.</p>
<p>To get the fakeportal fully authenticated, pass two request parameters:
<ul>
<li>client_id</li>
<li>client_secret</li>
</ul>
These credentitals are used to get an access token from UAA and send it to
RabbitMQ.
</p>

View File

@ -10,6 +10,7 @@ authnz-mgt/oauth-idp-initiated-with-uaa-and-prefix-via-proxy.sh
authnz-mgt/oauth-idp-initiated-with-uaa-and-prefix.sh
authnz-mgt/oauth-idp-initiated-with-uaa-via-proxy.sh
authnz-mgt/oauth-idp-initiated-with-uaa.sh
authnz-mgt/oauth-idp-initiated-with-oauth2-proxy-and-keycloak.sh
authnz-mgt/oauth-with-keycloak.sh
authnz-mgt/oauth-with-keycloak-with-verify-none.sh
authnz-mgt/oauth-with-uaa-down-but-with-basic-auth.sh

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEST_CASES_PATH=/oauth/with-idp-initiated
TEST_CONFIG_PATH=/oauth
PROFILES="oauth2-proxy keycloak keycloak-oauth-provider oauth2-proxy-mgt-oauth-provider tls"
source $SCRIPT/../../bin/suite_template $@
runWith keycloak oauth2-proxy

View File

@ -4,7 +4,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEST_CASES_PATH=/oauth/with-idp-initiated-via-proxy
TEST_CONFIG_PATH=/oauth
PROFILES="uaa fakeportal fakeproxy fakeportal-mgt-oauth-provider idp-initiated mgt-prefix uaa-oauth-provider"
PROFILES="uaa fakeportal fakeproxy fakeportal-mgt-oauth-provider idp-initiated mgt-prefix uaa-oauth-provider tls"
source $SCRIPT/../../bin/suite_template $@
runWith rabbitmq uaa fakeportal fakeproxy

View File

@ -4,7 +4,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEST_CASES_PATH=/oauth/with-idp-initiated
TEST_CONFIG_PATH=/oauth
PROFILES="uaa fakeportal-mgt-oauth-provider idp-initiated mgt-prefix uaa-oauth-provider"
PROFILES="uaa fakeportal-mgt-oauth-provider idp-initiated mgt-prefix uaa-oauth-provider tls"
source $SCRIPT/../../bin/suite_template $@
runWith uaa fakeportal

View File

@ -4,7 +4,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEST_CASES_PATH=/oauth/with-idp-initiated-via-proxy
TEST_CONFIG_PATH=/oauth
PROFILES="uaa fakeportal fakeproxy fakeportal-mgt-oauth-provider idp-initiated uaa-oauth-provider"
PROFILES="uaa fakeportal fakeproxy fakeportal-mgt-oauth-provider idp-initiated uaa-oauth-provider tls"
source $SCRIPT/../../bin/suite_template $@
runWith rabbitmq uaa fakeportal fakeproxy

View File

@ -4,7 +4,8 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEST_CASES_PATH=/oauth/with-idp-initiated
TEST_CONFIG_PATH=/oauth
PROFILES="uaa idp-initiated uaa-oauth-provider fakeportal-mgt-oauth-provider"
PROFILES="uaa uaa-oauth-provider idp-initiated fakeportal-mgt-oauth-provider tls"
source $SCRIPT/../../bin/suite_template $@
runWith uaa fakeportal
#runWith fakeportal

View File

@ -7,4 +7,5 @@ TEST_CONFIG_PATH=/oauth
PROFILES="uaa uaa-oauth-provider uaa-mgt-oauth-provider"
source $SCRIPT/../../bin/suite_template $@
initOnly uaa
run

View File

@ -1,3 +1,3 @@
export FAKEPORTAL_URL=http://fakeportal:3000
export FAKEPORTAL_URL=https://fakeportal:3000
export RABBITMQ_HOST_FOR_FAKEPORTAL=${RABBITMQ_HOST}
export UAA_URL_FOR_FAKEPORTAL=https://uaa:8443

View File

@ -1,3 +1,4 @@
export KEYCLOAK_URL=https://keycloak:8443/realms/test
export OAUTH_PROVIDER_URL=https://keycloak:8443/realms/test
export OAUTH_PROVIDER_CA_CERT=/config/oauth/keycloak/ca_keycloak_certificate.pem
export OAUTH_PROVIDER_URL=${KEYCLOAK_URL}
export KEYCLOAK_CA_CERT=/config/oauth/keycloak/ca_keycloak_certificate.pem
export OAUTH_PROVIDER_CA_CERT=${KEYCLOAK_CA_CERT}

View File

@ -0,0 +1,2 @@
export OAUTH2_PROXY_URL=https://oauth2-proxy:8442
export OAUTH2_PROXY_END_SESSION_URL=https://oauth2-proxy:8442/oauth2/sign_out?rd=https://keycloak:8443/realms/test/protocol/openid-connect/logout

View File

@ -1,3 +1,3 @@
export FAKEPORTAL_URL=http://localhost:3000
export FAKEPORTAL_URL=https://fakeportal:3000
export RABBITMQ_HOST_FOR_FAKEPORTAL=localhost:15672
export UAA_URL_FOR_FAKEPORTAL=https://uaa:8443

View File

@ -1,3 +1,4 @@
export KEYCLOAK_URL=https://localhost:8443/realms/test
export OAUTH_PROVIDER_URL=https://localhost:8443/realms/test
export OAUTH_PROVIDER_CA_CERT=selenium/test/oauth/keycloak/ca_keycloak_certificate.pem
export OAUTH_PROVIDER_URL=${KEYCLOAK_URL}
export KEYCLOAK_CA_CERT=selenium/test/oauth/keycloak/ca_keycloak_certificate.pem
export OAUTH_PROVIDER_CA_CERT=${KEYCLOAK_CA_CERT}

View File

@ -0,0 +1,2 @@
export OAUTH2_PROXY_URL=https://oauth2-proxy:8442
export OAUTH2_PROXY_END_SESSION_URL=https://localhost:8442/oauth2/sign_out?rd=https://keycloak:8443/realms/test/protocol/openid-connect/logout

View File

@ -0,0 +1,3 @@
[ client_alt_names ]
email.1 = rabbit_client@localhost
URI.1 = rabbit_client_id_uri

View File

@ -0,0 +1,37 @@
server:
BindAddress: 0.0.0.0:4180
SecureBindAddress: 0.0.0.0:8442
TLS:
Key:
FromFile: /etc/oauth2-proxy/server_oauth2-proxy_key.pem
Cert:
FromFile: /etc/oauth2-proxy/server_oauth2-proxy_certificate.pem
upstreamConfig:
upstreams:
- id: rabbitmq
path: /
uri: ${RABBITMQ_URL}
injectRequestHeaders:
- name: Authorization
values:
- claim: access_token
prefix: 'Bearer '
providers:
- provider: keycloak-oidc
id: keycloak-oidc
clientSecret: nt6pmZMeyrgzYgkg2MLgZQZxLveRMW5M
clientID: rabbitmq-proxy-client-tls
code_challenge_method: S256
scope: "email openid profile rabbitmq.tag:administrator"
skipClaimsFromProfileURL: true
caFiles:
- /etc/keycloak/ca_keycloak_certificate.pem
oidcConfig:
issuerURL: ${KEYCLOAK_URL}
insecureSkipNonce: true
audienceClaims:
- aud
emailClaim: sub
userIDClaim: user_name

View File

@ -1 +1,3 @@
management.oauth_provider_url = ${FAKEPORTAL_URL}
auth_oauth2.end_session_endpoint = ${FAKEPORTAL_URL}/logout
auth_oauth2.issuer = ${FAKEPORTAL_URL}

View File

@ -1 +1,2 @@
management.oauth_initiated_logon_type = idp_initiated

View File

@ -1,2 +1,2 @@
auth_oauth2.issuer = ${OAUTH_PROVIDER_URL}
auth_oauth2.https.cacertfile = ${OAUTH_PROVIDER_CA_CERT}
auth_oauth2.issuer = ${KEYCLOAK_URL}
auth_oauth2.https.cacertfile = ${KEYCLOAK_CA_CERT}

View File

@ -1,2 +1,2 @@
auth_oauth2.issuer = ${OAUTH_PROVIDER_URL}
auth_oauth2.issuer = ${KEYCLOAK_URL}
auth_oauth2.https.peer_verification = verify_none

View File

@ -0,0 +1,4 @@
auth_oauth2.end_session_endpoint = ${OAUTH2_PROXY_END_SESSION_URL}
management.oauth_provider_url = ${OAUTH2_PROXY_URL}
auth_oauth2.preferred_username_claims.1 = preferred_username

View File

@ -1,2 +1,4 @@
# uaa requires a secret in order to renew tokens
management.oauth_provider_url = ${UAA_URL}
# uaa requires a secret in order to renew tokens
management.oauth_client_secret = ${OAUTH_CLIENT_SECRET}

View File

@ -1,5 +1,3 @@
# uaa requires a secret in order to renew tokens
management.oauth_client_secret = ${OAUTH_CLIENT_SECRET}
# configure static signing keys and the oauth provider used by the plugin
auth_oauth2.default_key = ${OAUTH_SIGNING_KEY_ID}

View File

@ -19,6 +19,7 @@ logout:
disable: false
whitelist:
${RABBITMQ_SCHEME}://${RABBITMQ_HOST}/*
${FAKEPORTAL_URL}
login:
serviceProviderKey: |
-----BEGIN RSA PRIVATE KEY-----
@ -125,8 +126,9 @@ oauth:
id: admin
secret: adminsecret
authorized-grant-types: client_credentials
scope: none
authorities: uaa.admin,clients.admin,clients.read,clients.write,clients.secret,scim.write,scim.read,uaa.resource
scope: uaa.admin,clients.admin,clients.read,clients.write,clients.secret,scim.write,scim.read,uaa.resource,tokens.list
authorities: uaa.admin,clients.admin,clients.read,clients.write,clients.secret,scim.write,scim.read,uaa.resource,tokens.list
allowpublic: true
mgt_api_client:
id: mgt_api_client
secret: mgt_api_client
@ -146,7 +148,7 @@ oauth:
secret: rabbit_idp_user
authorized-grant-types: client_credentials
authorities: uaa.resource,rabbitmq.tag:administrator
redirect-uri: ${RABBITMQ_URL}
redirect-uri: ${FAKEPORTAL_URL}
autoapprove: true
allowpublic: true
mgt_api_client_2:

View File

@ -8,8 +8,6 @@ const OverviewPage = require('../../pageobjects/OverviewPage')
describe('A user with a JWT token', function () {
let overview
let captureScreen
let token
let fakePortal
before(async function () {
driver = buildDriver()

View File

@ -0,0 +1,36 @@
const { By, Key, until, Builder } = require('selenium-webdriver')
require('chromedriver')
const assert = require('assert')
const { buildDriver, goToHome, captureScreensFor, teardown, idpLoginPage } = require('../../utils')
const SSOHomePage = require('../../pageobjects/SSOHomePage')
const OverviewPage = require('../../pageobjects/OverviewPage')
describe('When a logged in user', function () {
let overview
let homePage
let captureScreen
let idpLogin
before(async function () {
driver = buildDriver()
overview = new OverviewPage(driver)
captureScreen = captureScreensFor(driver, __filename)
await goToHome(driver);
await overview.isLoaded()
assert.equal(await overview.getUser(), 'User rabbit_idp_user')
})
it('logs out', async function () {
await homePage.clickToLogin()
await idpLogin.login('rabbit_admin', 'rabbit_admin')
await overview.isLoaded()
await overview.logout()
await homePage.isLoaded()
})
after(async function () {
await teardown(driver, this, captureScreen)
})
})

View File

@ -1,7 +1,7 @@
const { By, Key, until, Builder } = require('selenium-webdriver')
require('chromedriver')
const assert = require('assert')
const { buildDriver, goToLogin, goTo, tokenFor, captureScreensFor, teardown } = require('../../utils')
const { buildDriver, captureScreensFor, teardown } = require('../../utils')
const OverviewPage = require('../../pageobjects/OverviewPage')
const FakePortalPage = require('../../pageobjects/FakePortalPage')
@ -9,7 +9,6 @@ const FakePortalPage = require('../../pageobjects/FakePortalPage')
describe('A user with a JWT token', function () {
let overview
let captureScreen
let token
let fakePortal
before(async function () {

View File

@ -1,7 +1,6 @@
const { By, Key, until, Builder } = require('selenium-webdriver')
require('chromedriver')
const assert = require('assert')
const { buildDriver, goToLogin, tokenFor, captureScreensFor, teardown } = require('../../utils')
const { buildDriver, captureScreensFor, teardown } = require('../../utils')
const OverviewPage = require('../../pageobjects/OverviewPage')
const FakePortalPage = require('../../pageobjects/FakePortalPage')

View File

@ -3,7 +3,7 @@ const { By, Key, until, Builder } = require('selenium-webdriver')
const BasePage = require('./BasePage')
const FORM = By.css('form#login_form')
const FAKE_PORTAL_URL = process.env.FAKE_PORTAL_URL || 'http://localhost:3000'
const FAKEPORTAL_URL = process.env.FAKEPORTAL_URL || 'https://localhost:3000'
module.exports = class FakePortalPage extends BasePage {
async isLoaded () {
@ -11,7 +11,7 @@ module.exports = class FakePortalPage extends BasePage {
}
async goToHome(client_id = undefined, client_secret = undefined) {
const url = new URL(FAKE_PORTAL_URL);
const url = new URL(FAKEPORTAL_URL);
if (typeof client_id !== 'undefined') url.searchParams.append("client_id", client_id);
if (typeof client_secret !== 'undefined') url.searchParams.append("client_secret", client_secret);
return this.driver.get(url.href);

View File

@ -128,7 +128,20 @@ module.exports = {
req.send()
if (req.status == 200) return JSON.parse(req.responseText)
else {
console.error(req.responseText)
console.error(JSON.stringify(req.statusText) + ", " + req.responseText)
throw new Error(req.responseText)
}
},
rest_get: (url, access_token) => {
const req = new XMLHttpRequest()
req.open('GET', url, false)
req.setRequestHeader('Accept', 'application/json')
req.setRequestHeader('Authorization', 'Bearer ' + access_token)
req.send()
if (req.status == 200) return JSON.parse(req.responseText)
else {
console.error(JSON.stringify(req.statusText) + ", " + req.responseText)
throw new Error(req.responseText)
}
},
@ -140,14 +153,13 @@ module.exports = {
'&grant_type=client_credentials' +
'&token_format=jwt' +
'&response_type=token'
req.open('POST', url, false)
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
req.setRequestHeader('Accept', 'application/json')
req.send(params)
if (req.status == 200) return JSON.parse(req.responseText).access_token
else {
console.error(req.responseText)
console.error(JSON.stringify(req.statusText) + ", " + req.responseText)
throw new Error(req.responseText)
}
},