From 56bd4ab212b0075e1d5cebd335eaf5b43a4ac707 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 6 Jun 2025 15:35:02 +0200 Subject: [PATCH 01/43] Add spring-authorization-server for selenium And ci job to build it --- .../workflows/authorization-server-make.yaml | 41 +++ selenium/authorization-server/.gitattributes | 2 + selenium/authorization-server/.gitignore | 33 +++ .../.mvn/wrapper/maven-wrapper.properties | 19 ++ selenium/authorization-server/dockerfile | 12 + selenium/authorization-server/mvnw | 259 ++++++++++++++++++ selenium/authorization-server/mvnw.cmd | 149 ++++++++++ selenium/authorization-server/pom.xml | 59 ++++ .../AuthorizationServerApplication.java | 13 + .../src/main/resources/application.properties | 1 + .../AuthorizationServerApplicationTests.java | 13 + 11 files changed, 601 insertions(+) create mode 100644 .github/workflows/authorization-server-make.yaml create mode 100644 selenium/authorization-server/.gitattributes create mode 100644 selenium/authorization-server/.gitignore create mode 100644 selenium/authorization-server/.mvn/wrapper/maven-wrapper.properties create mode 100644 selenium/authorization-server/dockerfile create mode 100755 selenium/authorization-server/mvnw create mode 100644 selenium/authorization-server/mvnw.cmd create mode 100644 selenium/authorization-server/pom.xml create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerApplication.java create mode 100644 selenium/authorization-server/src/main/resources/application.properties create mode 100644 selenium/authorization-server/src/test/java/com/rabbitmq/authorization_server/AuthorizationServerApplicationTests.java diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml new file mode 100644 index 000000000000..13097093ac3d --- /dev/null +++ b/.github/workflows/authorization-server-make.yaml @@ -0,0 +1,41 @@ +name: Spring Authorization Server docker image (make) + +on: + push: + branches: + - main + paths: + - .github/workflows/authorization-server-make.yaml + - selenium/authorization-server + pull_request: + paths: + - .github/workflows/authorization-server-make.yaml + - selenium/authorization-server + +env: + REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server + IMAGE_TAG: 0.0.1 +jobs: + docker: + runs-on: ubuntu-latest + steps: + + - name: CHECKOUT REPOSITORY + uses: actions/checkout@v4 + + - name: Prepare image + run: | + ls + echo "Building spring authorization server" + cd selenium/authorization-server + docker build . -t authorization-server + docker tag authorization-server ${{ env.REGISTRY_IMAGE }}:${{ env.IMAGE_TAG }} + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + - name: Push + run: | + docker push ${{ env.REGISTRY_IMAGE }}:${{ env.IMAGE_TAG }} \ No newline at end of file diff --git a/selenium/authorization-server/.gitattributes b/selenium/authorization-server/.gitattributes new file mode 100644 index 000000000000..3b41682ac579 --- /dev/null +++ b/selenium/authorization-server/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/selenium/authorization-server/.gitignore b/selenium/authorization-server/.gitignore new file mode 100644 index 000000000000..667aaef0c891 --- /dev/null +++ b/selenium/authorization-server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/selenium/authorization-server/.mvn/wrapper/maven-wrapper.properties b/selenium/authorization-server/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 000000000000..d58dfb70bab5 --- /dev/null +++ b/selenium/authorization-server/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/selenium/authorization-server/dockerfile b/selenium/authorization-server/dockerfile new file mode 100644 index 000000000000..1195192ff9c9 --- /dev/null +++ b/selenium/authorization-server/dockerfile @@ -0,0 +1,12 @@ +FROM maven:3.9.9-eclipse-temurin-24 as builder +WORKDIR /home/app +ADD . /home/app/authorization-server +RUN ./mvnw -Dmaven.test.skip=true clean package + +FROM openjdk:24-jdk +EXPOSE 8080 +ENTRYPOINT ["java","-jar","/authorization-server.jar"] +ARG JAR_FILE=target/*.jar +COPY --from=builder /home/app/authorization-server/target/*.jar authorization-server.jar + + diff --git a/selenium/authorization-server/mvnw b/selenium/authorization-server/mvnw new file mode 100755 index 000000000000..19529ddf8c6e --- /dev/null +++ b/selenium/authorization-server/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/selenium/authorization-server/mvnw.cmd b/selenium/authorization-server/mvnw.cmd new file mode 100644 index 000000000000..249bdf382222 --- /dev/null +++ b/selenium/authorization-server/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml new file mode 100644 index 000000000000..75c64867f179 --- /dev/null +++ b/selenium/authorization-server/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.5.0 + + + com.rabbitmq + authorization-server + 0.0.1-SNAPSHOT + authorization-server + Authorization Server for Selenium + + + + + + + + + + + + + + + 24 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-oauth2-authorization-server + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerApplication.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerApplication.java new file mode 100644 index 000000000000..853a77f92ab9 --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerApplication.java @@ -0,0 +1,13 @@ +package com.rabbitmq.authorization_server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AuthorizationServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AuthorizationServerApplication.class, args); + } + +} diff --git a/selenium/authorization-server/src/main/resources/application.properties b/selenium/authorization-server/src/main/resources/application.properties new file mode 100644 index 000000000000..53b0187e0a8c --- /dev/null +++ b/selenium/authorization-server/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.application.name=authorization-server diff --git a/selenium/authorization-server/src/test/java/com/rabbitmq/authorization_server/AuthorizationServerApplicationTests.java b/selenium/authorization-server/src/test/java/com/rabbitmq/authorization_server/AuthorizationServerApplicationTests.java new file mode 100644 index 000000000000..eae8ff431665 --- /dev/null +++ b/selenium/authorization-server/src/test/java/com/rabbitmq/authorization_server/AuthorizationServerApplicationTests.java @@ -0,0 +1,13 @@ +package com.rabbitmq.authorization_server; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class AuthorizationServerApplicationTests { + + @Test + void contextLoads() { + } + +} From 5312ed1986fbd33bd855437ce505db305fd731cb Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 6 Jun 2025 16:15:13 +0200 Subject: [PATCH 02/43] Fix issue in docker file --- selenium/authorization-server/dockerfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/selenium/authorization-server/dockerfile b/selenium/authorization-server/dockerfile index 1195192ff9c9..f303feef436b 100644 --- a/selenium/authorization-server/dockerfile +++ b/selenium/authorization-server/dockerfile @@ -1,7 +1,8 @@ -FROM maven:3.9.9-eclipse-temurin-24 as builder -WORKDIR /home/app -ADD . /home/app/authorization-server -RUN ./mvnw -Dmaven.test.skip=true clean package +FROM maven:3.9.9-eclipse-temurin-24-alpine as builder +WORKDIR /home/app/authorization-server +COPY ./ . +RUN mvn -Dmaven.test.skip=true clean package +# MAVEN_OPTS="--enable-native-access=ALL-UNNAMED" FROM openjdk:24-jdk EXPOSE 8080 From b3700ca6d9b8b906bfe9fadb76c3009b41fe6e8f Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 6 Jun 2025 16:41:30 +0200 Subject: [PATCH 03/43] Add behaviours --- selenium/authorization-server/dockerfile | 1 - .../authorization_server/SecurityConfig.java | 154 ++++++++++++++++++ .../src/main/resources/application.yml | 32 ++++ 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java create mode 100644 selenium/authorization-server/src/main/resources/application.yml diff --git a/selenium/authorization-server/dockerfile b/selenium/authorization-server/dockerfile index f303feef436b..a37ac795bb17 100644 --- a/selenium/authorization-server/dockerfile +++ b/selenium/authorization-server/dockerfile @@ -2,7 +2,6 @@ FROM maven:3.9.9-eclipse-temurin-24-alpine as builder WORKDIR /home/app/authorization-server COPY ./ . RUN mvn -Dmaven.test.skip=true clean package -# MAVEN_OPTS="--enable-native-access=ALL-UNNAMED" FROM openjdk:24-jdk EXPOSE 8080 diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java new file mode 100644 index 000000000000..9a900fe11e3d --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -0,0 +1,154 @@ +package com.rabbitmq.authorization_server; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.UUID; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.security.oauth2.core.oidc.OidcScopes; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; +import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; +import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; +import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; + +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.source.ImmutableJWKSet; +import com.nimbusds.jose.jwk.source.JWKSource; +import com.nimbusds.jose.proc.SecurityContext; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + @Order(1) + public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) + throws Exception { + OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = + OAuth2AuthorizationServerConfigurer.authorizationServer(); + + http + .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher()) + .with(authorizationServerConfigurer, (authorizationServer) -> + authorizationServer + .oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0 + ) + .authorizeHttpRequests((authorize) -> + authorize + .anyRequest().authenticated() + ) + // Redirect to the login page when not authenticated from the + // authorization endpoint + .exceptionHandling((exceptions) -> exceptions + .defaultAuthenticationEntryPointFor( + new LoginUrlAuthenticationEntryPoint("/login"), + new MediaTypeRequestMatcher(MediaType.TEXT_HTML) + ) + ); + + return http.build(); + } + + @Bean + @Order(2) + public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) + throws Exception { + http + .authorizeHttpRequests((authorize) -> authorize + .anyRequest().authenticated() + ) + // Form login handles the redirect to the login page from the + // authorization server filter chain + .formLogin(Customizer.withDefaults()); + + return http.build(); + } + + @Bean + public UserDetailsService userDetailsService() { + UserDetails userDetails = User.withDefaultPasswordEncoder() + .username("user") + .password("password") + .roles("USER") + .build(); + + return new InMemoryUserDetailsManager(userDetails); + } + + @Bean + public RegisteredClientRepository registeredClientRepository() { + RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString()) + .clientId("oidc-client") + .clientSecret("{noop}secret") + .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) + .redirectUri("http://127.0.0.1:8080/login/oauth2/code/oidc-client") + .postLogoutRedirectUri("http://127.0.0.1:8080/") + .scope(OidcScopes.OPENID) + .scope(OidcScopes.PROFILE) + .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) + .build(); + + return new InMemoryRegisteredClientRepository(oidcClient); + } + + @Bean + public JWKSource jwkSource() { + KeyPair keyPair = generateRsaKey(); + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + RSAKey rsaKey = new RSAKey.Builder(publicKey) + .privateKey(privateKey) + .keyID(UUID.randomUUID().toString()) + .build(); + JWKSet jwkSet = new JWKSet(rsaKey); + return new ImmutableJWKSet<>(jwkSet); + } + + private static KeyPair generateRsaKey() { + KeyPair keyPair; + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + keyPair = keyPairGenerator.generateKeyPair(); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + return keyPair; + } + + @Bean + public JwtDecoder jwtDecoder(JWKSource jwkSource) { + return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); + } + + @Bean + public AuthorizationServerSettings authorizationServerSettings() { + return AuthorizationServerSettings.builder().build(); + } + +} diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml new file mode 100644 index 000000000000..1f6846c42fce --- /dev/null +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -0,0 +1,32 @@ +server: + port: 8080 + +logging: + level: + org.springframework.security: trace + +spring: + security: + user: + name: user + password: password + oauth2: + authorizationserver: + client: + oidc-client: + registration: + client-id: "oidc-client" + client-secret: "{noop}secret" + client-authentication-methods: + - "client_secret_basic" + authorization-grant-types: + - "authorization_code" + - "refresh_token" + redirect-uris: + - "http://127.0.0.1:15672/login/oauth2/code/oidc-client" + post-logout-redirect-uris: + - "http://127.0.0.1:15672/" + scopes: + - "openid" + - "profile" + require-authorization-consent: true \ No newline at end of file From 832fe7837348d03e7818a3390d3aaaedcc6afd47 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 6 Jun 2025 17:11:01 +0200 Subject: [PATCH 04/43] Prepare all scripts to deploy spring authorization server --- selenium/bin/components/spring | 49 +++++++++++++++++++ selenium/bin/gen-spring-yml | 20 ++++++++ .../oauth-with-spring-authz-server.sh | 10 ++++ 3 files changed, 79 insertions(+) create mode 100644 selenium/bin/components/spring create mode 100755 selenium/bin/gen-spring-yml create mode 100755 selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring new file mode 100644 index 000000000000..fcfffc772a57 --- /dev/null +++ b/selenium/bin/components/spring @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server + +ensure_spring() { + if docker ps | grep spring &> /dev/null; then + print "spring already running ..." + else + start_spring + fi +} +init_spring() { + SPRING_CONFIG_PATH=${SPRING_CONFIG_PATH:-oauth/spring} + SPRING_CONFIG_DIR=$(realpath ${TEST_DIR}/${SPRING_CONFIG_PATH}) + SPRING_URL=${SPRING_URL:-OAUTH_PROVIDER_URL} + + print "> SPRING_CONFIG_DIR: ${SPRING_CONFIG_DIR}" + print "> SPRING_URL: ${SPRING_URL}" + print "> SPRING_DOCKER_IMAGE: ${SPRING_DOCKER_IMAGE}" + + generate-ca-server-client-kpi spring $SPRING_CONFIG_DIR + +} +start_spring() { + begin "Starting spring ..." + + init_spring + kill_container_if_exist spring + + MOUNT_SPRING_CONF_DIR=$CONF_DIR/spring + + mkdir -p $MOUNT_SPRING_CONF_DIR +# ${BIN_DIR}/gen-spring-yml ${SPRINGCONFIG_DIR} "test-realm" $ENV_FILE $MOUNT_KEYCLOAK_CONF_DIR/test-realm.json + print "> EFFECTIVE SPRING_CONFIG_FILE: $MOUNT_SPRING_CONF_DIR/application.yml" + cp ${SPRING_CONFIG_DIR}/*.pem $MOUNT_SPRING_CONF_DIR + + docker run \ + --detach \ + --name spring \ + --net ${DOCKER_NETWORK} \ + --publish 8081:8080 \ + --publish 8443:8443 \ + -v ${MOUNT_SPRING_CONF_DIR}:/opt/spring/data/import/ \ + ${SPRING_DOCKER_IMAGE} + + wait_for_oidc_endpoint spring $SPRING_URL $MOUNT_SPRING_CONF_DIR/ca_spring_certificate.pem + end "spring is ready" + +} diff --git a/selenium/bin/gen-spring-yml b/selenium/bin/gen-spring-yml new file mode 100755 index 000000000000..c32d8fb1ee81 --- /dev/null +++ b/selenium/bin/gen-spring-yml @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +#set -x + +SPRING_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 "${PROFILES}" $SPRING_PATH "application" "yml") +do + envsubst < $f >> $FINAL_CONFIG_FILE +done diff --git a/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh b/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh new file mode 100755 index 000000000000..ea177e1b7172 --- /dev/null +++ b/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +TEST_CASES_PATH=/oauth/with-sp-initiated +TEST_CONFIG_PATH=/oauth +PROFILES="spring-authz-server spring-oauth-provider spring-mgt-oauth-provider tls" + +source $SCRIPT/../../bin/suite_template $@ +runWith spring-authz-server From 4ac352436b258196e3e1263ba48a0a80847be453 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 11 Jun 2025 14:16:31 +0200 Subject: [PATCH 05/43] Add config files for spring auth server --- .../com/rabbitmq/authorization_server/SecurityConfig.java | 6 +++--- .../suites/authnz-mgt/oauth-with-spring-authz-server.sh | 4 ++-- selenium/test/oauth/env.docker.spring | 2 ++ selenium/test/oauth/env.local.spring | 3 +++ selenium/test/oauth/env.spring-oauth-provider | 2 ++ selenium/test/oauth/spring/openssl.cnf.in | 3 +++ 6 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 selenium/test/oauth/env.docker.spring create mode 100644 selenium/test/oauth/env.local.spring create mode 100644 selenium/test/oauth/env.spring-oauth-provider create mode 100644 selenium/test/oauth/spring/openssl.cnf.in diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 9a900fe11e3d..249e2b8b53ba 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -89,9 +89,9 @@ public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) @Bean public UserDetailsService userDetailsService() { UserDetails userDetails = User.withDefaultPasswordEncoder() - .username("user") - .password("password") - .roles("USER") + .username("admin") + .password("admin") + .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(userDetails); diff --git a/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh b/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh index ea177e1b7172..fd1f3cce3ae7 100755 --- a/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh +++ b/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh @@ -4,7 +4,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/oauth/with-sp-initiated TEST_CONFIG_PATH=/oauth -PROFILES="spring-authz-server spring-oauth-provider spring-mgt-oauth-provider tls" +PROFILES="spring spring-oauth-provider spring-mgt-oauth-provider tls" source $SCRIPT/../../bin/suite_template $@ -runWith spring-authz-server +runWith spring diff --git a/selenium/test/oauth/env.docker.spring b/selenium/test/oauth/env.docker.spring new file mode 100644 index 000000000000..60b66456b475 --- /dev/null +++ b/selenium/test/oauth/env.docker.spring @@ -0,0 +1,2 @@ +export SPRING_URL=https://spring:8443/ +export SPRING_CA_CERT=/config/oauth/spring/ca_spring_certificate.pem diff --git a/selenium/test/oauth/env.local.spring b/selenium/test/oauth/env.local.spring new file mode 100644 index 000000000000..8bb10da7d278 --- /dev/null +++ b/selenium/test/oauth/env.local.spring @@ -0,0 +1,3 @@ +export SPRING_URL=https://localhost:8080/ +export OAUTH_PROVIDER_URL=${SPRING_URL} +export SPRING_CA_CERT=selenium/test/oauth/spring/ca_spring_certificate.pem diff --git a/selenium/test/oauth/env.spring-oauth-provider b/selenium/test/oauth/env.spring-oauth-provider new file mode 100644 index 000000000000..979500cb8bd1 --- /dev/null +++ b/selenium/test/oauth/env.spring-oauth-provider @@ -0,0 +1,2 @@ +export OAUTH_PROVIDER_URL=${SPRING_URL} +export OAUTH_PROVIDER_CA_CERT=${SPRING_CA_CERT} diff --git a/selenium/test/oauth/spring/openssl.cnf.in b/selenium/test/oauth/spring/openssl.cnf.in new file mode 100644 index 000000000000..5ac3282046c5 --- /dev/null +++ b/selenium/test/oauth/spring/openssl.cnf.in @@ -0,0 +1,3 @@ +[ client_alt_names ] +email.1 = rabbit_client@localhost +URI.1 = rabbit_client_id_uri From 7b394dccd38d9bfa8250d39842523cf4323ee19f Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 11 Jun 2025 14:59:32 +0200 Subject: [PATCH 06/43] Fix issue starting spring And add missing configuration --- selenium/bin/components/spring | 11 ++++++----- selenium/test/oauth/spring/application.yml | 9 +++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) mode change 100644 => 100755 selenium/bin/components/spring create mode 100644 selenium/test/oauth/spring/application.yml diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring old mode 100644 new mode 100755 index fcfffc772a57..695dd6561938 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -1,6 +1,6 @@ #!/usr/bin/env bash -SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server +SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.1 ensure_spring() { if docker ps | grep spring &> /dev/null; then @@ -19,7 +19,7 @@ init_spring() { print "> SPRING_DOCKER_IMAGE: ${SPRING_DOCKER_IMAGE}" generate-ca-server-client-kpi spring $SPRING_CONFIG_DIR - + generate-server-keystore-if-required spring $SPRING_CONFIG_DIR } start_spring() { begin "Starting spring ..." @@ -30,7 +30,7 @@ start_spring() { MOUNT_SPRING_CONF_DIR=$CONF_DIR/spring mkdir -p $MOUNT_SPRING_CONF_DIR -# ${BIN_DIR}/gen-spring-yml ${SPRINGCONFIG_DIR} "test-realm" $ENV_FILE $MOUNT_KEYCLOAK_CONF_DIR/test-realm.json + ${BIN_DIR}/gen-spring-yml ${SPRING_CONFIG_DIR} $ENV_FILE $MOUNT_SPRING_CONF_DIR/application.yml print "> EFFECTIVE SPRING_CONFIG_FILE: $MOUNT_SPRING_CONF_DIR/application.yml" cp ${SPRING_CONFIG_DIR}/*.pem $MOUNT_SPRING_CONF_DIR @@ -38,8 +38,9 @@ start_spring() { --detach \ --name spring \ --net ${DOCKER_NETWORK} \ - --publish 8081:8080 \ - --publish 8443:8443 \ + --publish 8080:8080 \ + --publish 8443:8443 \ + -v ${MOUNT_SPRING_CONF_DIR}:/config \ -v ${MOUNT_SPRING_CONF_DIR}:/opt/spring/data/import/ \ ${SPRING_DOCKER_IMAGE} diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml new file mode 100644 index 000000000000..23c82ad3a523 --- /dev/null +++ b/selenium/test/oauth/spring/application.yml @@ -0,0 +1,9 @@ +server: + ssl: + enabled: true + protocol: TLS + enabled-protocols: TLSv1.2 + key-store-type: PKCS12 + ssl.key-store: /config/server_spring.p12 + ssl.key-store-password: guest + port: 8080 From a3de494b79845d39bbd5875a3f04ead042a986be Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 11 Jun 2025 15:45:39 +0200 Subject: [PATCH 07/43] Configure spring with tls --- selenium/bin/components/spring | 2 +- selenium/test/oauth/spring/application.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring index 695dd6561938..a882bd1c55ff 100755 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -33,6 +33,7 @@ start_spring() { ${BIN_DIR}/gen-spring-yml ${SPRING_CONFIG_DIR} $ENV_FILE $MOUNT_SPRING_CONF_DIR/application.yml print "> EFFECTIVE SPRING_CONFIG_FILE: $MOUNT_SPRING_CONF_DIR/application.yml" cp ${SPRING_CONFIG_DIR}/*.pem $MOUNT_SPRING_CONF_DIR + cp ${SPRING_CONFIG_DIR}/*.jks $MOUNT_SPRING_CONF_DIR docker run \ --detach \ @@ -41,7 +42,6 @@ start_spring() { --publish 8080:8080 \ --publish 8443:8443 \ -v ${MOUNT_SPRING_CONF_DIR}:/config \ - -v ${MOUNT_SPRING_CONF_DIR}:/opt/spring/data/import/ \ ${SPRING_DOCKER_IMAGE} wait_for_oidc_endpoint spring $SPRING_URL $MOUNT_SPRING_CONF_DIR/ca_spring_certificate.pem diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index 23c82ad3a523..91461588cd4c 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -4,6 +4,6 @@ server: protocol: TLS enabled-protocols: TLSv1.2 key-store-type: PKCS12 - ssl.key-store: /config/server_spring.p12 - ssl.key-store-password: guest + key-store: /config/server_spring.jks + key-store-password: foobar port: 8080 From 19b440c9d81043cf0ae6ef36d4e008db01c3fe8a Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 11 Jun 2025 16:59:45 +0200 Subject: [PATCH 08/43] Deploy spring auth server with tls --- selenium/test/oauth/env.docker.spring | 2 +- selenium/test/oauth/env.local.spring | 2 +- selenium/test/oauth/spring/application.yml | 23 +++++++++++++++------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/selenium/test/oauth/env.docker.spring b/selenium/test/oauth/env.docker.spring index 60b66456b475..78a0af0cc08a 100644 --- a/selenium/test/oauth/env.docker.spring +++ b/selenium/test/oauth/env.docker.spring @@ -1,2 +1,2 @@ -export SPRING_URL=https://spring:8443/ +export SPRING_URL=https://spring:8443 export SPRING_CA_CERT=/config/oauth/spring/ca_spring_certificate.pem diff --git a/selenium/test/oauth/env.local.spring b/selenium/test/oauth/env.local.spring index 8bb10da7d278..20f8c16cd943 100644 --- a/selenium/test/oauth/env.local.spring +++ b/selenium/test/oauth/env.local.spring @@ -1,3 +1,3 @@ -export SPRING_URL=https://localhost:8080/ +export SPRING_URL=https://localhost:8443 export OAUTH_PROVIDER_URL=${SPRING_URL} export SPRING_CA_CERT=selenium/test/oauth/spring/ca_spring_certificate.pem diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index 91461588cd4c..c1cf36f4c9e0 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -1,9 +1,18 @@ server: + port: 8443 ssl: - enabled: true - protocol: TLS - enabled-protocols: TLSv1.2 - key-store-type: PKCS12 - key-store: /config/server_spring.jks - key-store-password: foobar - port: 8080 + bundle: spring-authorizationserver + +spring: + ssl: + bundle: + jks: + spring-authorizationserver: + key: + alias: server-spring-tls + password: foobar + keystore: + location: /config/server_spring.jks + password: foobar + type: PKCS12 + \ No newline at end of file From 4320b666fcdf3620fc1220422592c12458e94503 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 09:01:43 +0200 Subject: [PATCH 09/43] Add CORS filter Otherwise RabbitMQ cannot reach the discovery endpoint from the browser --- .../SimpleCORSFilter.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java new file mode 100644 index 000000000000..49ddf71a6529 --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java @@ -0,0 +1,63 @@ +package com.rabbitmq.authorization_server; + +import java.io.IOException; +import java.util.Optional; +import java.util.Set; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Component +@Order(Ordered.HIGHEST_PRECEDENCE) +public class SimpleCORSFilter implements Filter { + + private final Set allowedOrigins; + + @Autowired + public SimpleCORSFilter(@Value("${spring.security.cors.allowed-origins:*}") Set allowedOrigins) { + this.allowedOrigins = allowedOrigins; + } + + @Override + public void init(FilterConfig fc) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest req, ServletResponse resp, + FilterChain chain) throws IOException, ServletException { + HttpServletResponse response = (HttpServletResponse) resp; + HttpServletRequest request = (HttpServletRequest) req; + String origin = request.getHeader("referer"); + if(origin != null ){ + Optional first = allowedOrigins.stream().filter(origin::startsWith).findFirst(); + first.ifPresent(s -> response.setHeader("Access-Control-Allow-Origin", s)); + } + response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); + response.setHeader("Access-Control-Max-Age", "3600"); + response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN"); + + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { + response.setStatus(HttpServletResponse.SC_OK); + } else { + chain.doFilter(req, resp); + } + } + + @Override + public void destroy() { + } + +} From 7a9c80a3be21790d9f4da97012cada1ced53e546 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 09:02:30 +0200 Subject: [PATCH 10/43] Add missing config And simplify suite name --- ...g-authz-server.sh => oauth-with-spring.sh} | 2 +- selenium/test/oauth/env.spring | 2 ++ .../oauth/rabbitmq.spring-oauth-provider.conf | 2 ++ selenium/test/oauth/spring/application.yml | 24 ++++++++++++++++++- 4 files changed, 28 insertions(+), 2 deletions(-) rename selenium/suites/authnz-mgt/{oauth-with-spring-authz-server.sh => oauth-with-spring.sh} (74%) create mode 100644 selenium/test/oauth/env.spring create mode 100644 selenium/test/oauth/rabbitmq.spring-oauth-provider.conf diff --git a/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh b/selenium/suites/authnz-mgt/oauth-with-spring.sh similarity index 74% rename from selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh rename to selenium/suites/authnz-mgt/oauth-with-spring.sh index fd1f3cce3ae7..583875f677d3 100755 --- a/selenium/suites/authnz-mgt/oauth-with-spring-authz-server.sh +++ b/selenium/suites/authnz-mgt/oauth-with-spring.sh @@ -4,7 +4,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/oauth/with-sp-initiated TEST_CONFIG_PATH=/oauth -PROFILES="spring spring-oauth-provider spring-mgt-oauth-provider tls" +PROFILES="spring spring-oauth-provider tls" source $SCRIPT/../../bin/suite_template $@ runWith spring diff --git a/selenium/test/oauth/env.spring b/selenium/test/oauth/env.spring new file mode 100644 index 000000000000..405e1d60fc8f --- /dev/null +++ b/selenium/test/oauth/env.spring @@ -0,0 +1,2 @@ +export OAUTH_SERVER_CONFIG_DIR=${OAUTH_SERVER_CONFIG_BASEDIR}/oauth/spring +export OAUTH_SCOPES="openid profile rabbitmq.tag:management" diff --git a/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf b/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf new file mode 100644 index 000000000000..704f479f62b2 --- /dev/null +++ b/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf @@ -0,0 +1,2 @@ +auth_oauth2.issuer = ${SPRING_URL} +auth_oauth2.https.cacertfile = ${SPRING_CA_CERT} diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index c1cf36f4c9e0..85817c7c3609 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -15,4 +15,26 @@ spring: location: /config/server_spring.jks password: foobar type: PKCS12 - \ No newline at end of file + security: + oauth2: + client: + registration: + mgt_api_client: + provider: spring + client-id: mgt_api_client + authorization-grant-type: client_credentials + scopes: + - openid + - profile + - rabbitmq.tag:management + client-name: mgt_api_client + rabbitmq_client_code: + provider: spring + client-id: rabbitmq_client_code + authorization-grant-type: authorization_code + redirect-uri: "https://localhost:15671/js/oidc-oauth/login-callback.html" + scopes: + - openid + - profile + - rabbitmq.tag:administrator + client-name: rabbitmq_client_code \ No newline at end of file From c7322884a34919f55e333478e8eb29dd9f80e19e Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 09:10:39 +0200 Subject: [PATCH 11/43] Bump up version of spring auth server --- selenium/authorization-server/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index 75c64867f179..0f7a13caf9b7 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.1-SNAPSHOT + 0.0.2 authorization-server Authorization Server for Selenium From 5afa696c52bac8ec57a2fc2543b0d15da0b72e0c Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 09:11:34 +0200 Subject: [PATCH 12/43] Bump spring auth server to 0.0.2 --- .github/workflows/authorization-server-make.yaml | 2 +- selenium/bin/components/spring | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index 13097093ac3d..25765838ae80 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.1 + IMAGE_TAG: 0.0.2 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring index a882bd1c55ff..86ef1cfdd144 100755 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -1,6 +1,6 @@ #!/usr/bin/env bash -SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.1 +SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.2 ensure_spring() { if docker ps | grep spring &> /dev/null; then From d4fd7f3007f0150e7abaf6434482d3007fd7f7ed Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 09:57:02 +0200 Subject: [PATCH 13/43] Use * for any CORS origin At least for now --- .github/workflows/authorization-server-make.yaml | 2 +- selenium/authorization-server/pom.xml | 2 +- .../authorization_server/SimpleCORSFilter.java | 14 ++++---------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index 25765838ae80..daef613fbc57 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.2 + IMAGE_TAG: 0.0.3 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index 0f7a13caf9b7..431f2b41c625 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.2 + 0.0.3 authorization-server Authorization Server for Selenium diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java index 49ddf71a6529..af07557665e0 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java @@ -23,28 +23,22 @@ @Order(Ordered.HIGHEST_PRECEDENCE) public class SimpleCORSFilter implements Filter { - private final Set allowedOrigins; - @Autowired - public SimpleCORSFilter(@Value("${spring.security.cors.allowed-origins:*}") Set allowedOrigins) { - this.allowedOrigins = allowedOrigins; + public SimpleCORSFilter() { } @Override public void init(FilterConfig fc) throws ServletException { - + System.out.println("Init SimpleCORSFilter"); } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { + System.out.println("doFilter SimpleCORSFilter"); HttpServletResponse response = (HttpServletResponse) resp; HttpServletRequest request = (HttpServletRequest) req; - String origin = request.getHeader("referer"); - if(origin != null ){ - Optional first = allowedOrigins.stream().filter(origin::startsWith).findFirst(); - first.ifPresent(s -> response.setHeader("Access-Control-Allow-Origin", s)); - } + response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN"); From 274e9084d09ae3cba165384f60c7a73261503874 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 13:49:31 +0200 Subject: [PATCH 14/43] Disable client registry and enable user registry --- .../workflows/authorization-server-make.yaml | 2 +- selenium/authorization-server/pom.xml | 2 +- ...AuthorizationServerUserDetailsService.java | 47 +++++++++++++++++++ .../authorization_server/SecurityConfig.java | 10 ++-- 4 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index daef613fbc57..1856c912cbc9 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.3 + IMAGE_TAG: 0.0.4 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index 431f2b41c625..925062afd86e 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.3 + 0.0.4 authorization-server Authorization Server for Selenium diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java new file mode 100644 index 000000000000..d33f2963cdbe --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java @@ -0,0 +1,47 @@ +package com.rabbitmq.authorization_server; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import jakarta.annotation.PostConstruct; + +public class AuthorizationServerUserDetailsService implements UserDetailsService { + + private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationServerUserDetailsService.class); + + private final Map usersByUsername = new HashMap<>(); + + public AuthorizationServerUserDetailsService() { + + } + UserDetails ud; + + @PostConstruct + public void initUsers() { + List roles = List.of("openid", "profile", "rabbitmq.tag:administrator").stream().map(scope -> + new SimpleGrantedAuthority(scope)).toList(); + User rabbit_admin = new User("rabbit_admin", "rabbit_admin", roles); + + usersByUsername.put(rabbit_admin.getUsername(), rabbit_admin); + + LOGGER.info("Initialized users {}, {} and {}", rabbit_admin); + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + if (usersByUsername.containsKey(username)) { + LOGGER.info("Found user for {}", username); + return usersByUsername.get(username); + } else { + LOGGER.warn("No user found for {}", username); + throw new UsernameNotFoundException("No user found for " + username); + } + } +} \ No newline at end of file diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 249e2b8b53ba..28ab18a2b628 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -89,14 +89,14 @@ public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) @Bean public UserDetailsService userDetailsService() { UserDetails userDetails = User.withDefaultPasswordEncoder() - .username("admin") - .password("admin") - .roles("ADMIN") + .username("rabbit_admin") + .password("rabbit_admin") + .roles("openid profile rabbitmq.tag:administrator") .build(); return new InMemoryUserDetailsManager(userDetails); } - +/* @Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString()) @@ -114,7 +114,7 @@ public RegisteredClientRepository registeredClientRepository() { return new InMemoryRegisteredClientRepository(oidcClient); } - + */ @Bean public JWKSource jwkSource() { KeyPair keyPair = generateRsaKey(); From 68a723b005d137804e888032d0e0803d2838d04b Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 15:13:36 +0200 Subject: [PATCH 15/43] Fix configuration errors --- .../ClientController.java | 20 ++++++ .../src/main/resources/application.yml | 68 ++++++++++++------- selenium/bin/components/spring | 2 +- selenium/test/oauth/spring/application.yml | 50 ++++++++------ 4 files changed, 96 insertions(+), 44 deletions(-) create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ClientController.java diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ClientController.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ClientController.java new file mode 100644 index 000000000000..00474a941d1d --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ClientController.java @@ -0,0 +1,20 @@ +package com.rabbitmq.authorization_server; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ClientController { + + @Autowired + private RegisteredClientRepository registeredClientRepository; + + @GetMapping("/api/client") + public RegisteredClient findClientById(@RequestParam String clientId) { + return registeredClientRepository.findByClientId(clientId); + } +} \ No newline at end of file diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index 1f6846c42fce..37b6299535ed 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -1,32 +1,52 @@ server: - port: 8080 - -logging: - level: - org.springframework.security: trace - + port: 8443 + ssl: + bundle: spring-authorizationserver + spring: + ssl: + bundle: + jks: + spring-authorizationserver: + key: + alias: server-spring-tls + password: foobar + keystore: + location: ../test/oauth/spring/server_spring.jks + password: foobar + type: PKCS12 security: - user: - name: user - password: password oauth2: authorizationserver: client: - oidc-client: + mgt_api_client: registration: - client-id: "oidc-client" - client-secret: "{noop}secret" + provider: spring + client-id: mgt_api_client + authorization-grant-types: + - client_credentials client-authentication-methods: - - "client_secret_basic" - authorization-grant-types: - - "authorization_code" - - "refresh_token" - redirect-uris: - - "http://127.0.0.1:15672/login/oauth2/code/oidc-client" - post-logout-redirect-uris: - - "http://127.0.0.1:15672/" - scopes: - - "openid" - - "profile" - require-authorization-consent: true \ No newline at end of file + - client_secret_basic + require-proof-key: true + scopes: + - openid + - profile + - rabbitmq.tag:management + client-name: mgt_api_client + rabbitmq_client_code: + registration: + provider: spring + client-id: rabbitmq_client_code + authorization-grant-types: + - authorization_code + client-authentication-methods: + - none + redirect-uris: + - "https://localhost:15671/js/oidc-oauth/login-callback.html" + scopes: + - openid + - profile + - rabbitmq.tag:administrator + client-name: rabbitmq_client_code + + \ No newline at end of file diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring index 86ef1cfdd144..03c22f053d31 100755 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -1,6 +1,6 @@ #!/usr/bin/env bash -SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.2 +SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.4 ensure_spring() { if docker ps | grep spring &> /dev/null; then diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index 85817c7c3609..22731df7568c 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -17,24 +17,36 @@ spring: type: PKCS12 security: oauth2: - client: - registration: + authorizationserver: + client: mgt_api_client: - provider: spring - client-id: mgt_api_client - authorization-grant-type: client_credentials - scopes: - - openid - - profile - - rabbitmq.tag:management - client-name: mgt_api_client + registration: + provider: spring + client-id: mgt_api_client + authorization-grant-types: + - client_credentials + client-authentication-methods: + - client_secret_basic + require-proof-key: true + scopes: + - openid + - profile + - rabbitmq.tag:management + client-name: mgt_api_client rabbitmq_client_code: - provider: spring - client-id: rabbitmq_client_code - authorization-grant-type: authorization_code - redirect-uri: "https://localhost:15671/js/oidc-oauth/login-callback.html" - scopes: - - openid - - profile - - rabbitmq.tag:administrator - client-name: rabbitmq_client_code \ No newline at end of file + registration: + provider: spring + client-id: rabbitmq_client_code + authorization-grant-types: + - authorization_code + client-authentication-methods: + - none + redirect-uris: + - "https://localhost:15671/js/oidc-oauth/login-callback.html" + scopes: + - openid + - profile + - rabbitmq.tag:administrator + client-name: rabbitmq_client_code + + \ No newline at end of file From f8e01daf7e5d9bfcdaa76d7dab962a6f2454f2e8 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 15:43:05 +0200 Subject: [PATCH 16/43] Fix configuration Still missing audience claim from token --- .../authorization-server/src/main/resources/application.yml | 1 + selenium/test/oauth/rabbitmq.conf | 2 ++ selenium/test/oauth/spring/application.yml | 1 + 3 files changed, 4 insertions(+) diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index 37b6299535ed..daafd5bf944d 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -47,6 +47,7 @@ spring: - openid - profile - rabbitmq.tag:administrator + - rabbitmq.tag:management client-name: rabbitmq_client_code \ No newline at end of file diff --git a/selenium/test/oauth/rabbitmq.conf b/selenium/test/oauth/rabbitmq.conf index f101bae111c0..2d96ff93e534 100644 --- a/selenium/test/oauth/rabbitmq.conf +++ b/selenium/test/oauth/rabbitmq.conf @@ -1,5 +1,7 @@ auth_backends.1 = rabbit_auth_backend_oauth2 +log.console.level = debug + management.login_session_timeout = 1 management.oauth_enabled = true management.oauth_client_id = rabbitmq_client_code diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index 22731df7568c..fd429d3980ce 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -47,6 +47,7 @@ spring: - openid - profile - rabbitmq.tag:administrator + - rabbitmq.tag:management client-name: rabbitmq_client_code \ No newline at end of file From 287e8d715db6c2500ffdf7f7943f54eb98b54b53 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 12 Jun 2025 17:14:14 +0200 Subject: [PATCH 17/43] Add scopes and aud claim to token --- .../AudienceAuthority.java | 23 ++++++++++++++++ .../authorization_server/ScopeAuthority.java | 22 +++++++++++++++ .../authorization_server/SecurityConfig.java | 27 ++++++++++++++++++- 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java new file mode 100644 index 000000000000..74a33cb22403 --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java @@ -0,0 +1,23 @@ +package com.rabbitmq.authorization_server; + +import org.springframework.security.core.GrantedAuthority; + +public class AudienceAuthority implements GrantedAuthority { + + private String authority; + + + public AudienceAuthority(String value) { + this.authority = value; + } + + public static AudienceAuthority aud(String value) { + return new AudienceAuthority(value); + } + + @Override + public String getAuthority() { + return authority; + } + +} \ No newline at end of file diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java new file mode 100644 index 000000000000..b863a625b3d6 --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java @@ -0,0 +1,22 @@ +package com.rabbitmq.authorization_server; + +import org.springframework.security.core.GrantedAuthority; + +public class ScopeAuthority implements GrantedAuthority { + + private String authority; + + public ScopeAuthority(String value) { + this.authority = value; + } + + public static ScopeAuthority scope(String value) { + return new ScopeAuthority(value); + } + + @Override + public String getAuthority() { + return authority; + } + +} \ No newline at end of file diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 28ab18a2b628..080a3fc36011 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -4,6 +4,7 @@ import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; +import java.util.List; import java.util.UUID; import org.springframework.context.annotation.Bean; @@ -20,6 +21,7 @@ import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; @@ -27,6 +29,8 @@ import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; +import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @@ -38,6 +42,9 @@ import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; +import static com.rabbitmq.authorization_server.ScopeAuthority.scope; +import static com.rabbitmq.authorization_server.AudienceAuthority.aud; + @Configuration @EnableWebSecurity public class SecurityConfig { @@ -91,7 +98,11 @@ public UserDetailsService userDetailsService() { UserDetails userDetails = User.withDefaultPasswordEncoder() .username("rabbit_admin") .password("rabbit_admin") - .roles("openid profile rabbitmq.tag:administrator") + .authorities(List.of( + scope("openid"), + scope("profile"), + scope("rabbitmq.tag:administrator"), + aud("rabbitmq"))) .build(); return new InMemoryUserDetailsManager(userDetails); @@ -141,6 +152,20 @@ private static KeyPair generateRsaKey() { return keyPair; } + @Bean + public OAuth2TokenCustomizer jwtTokenCustomizer() { + return (context) -> { + if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { + System.out.println("Principal: " + context.getPrincipal()); + System.out.println("Authorized scopes: " + context.getAuthorizedScopes()); + context.getClaims().claims((claims) -> { + claims.put("aud", "rabbitmq"); + }); + } + }; + } + + @Bean public JwtDecoder jwtDecoder(JWKSource jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); From 308b392c844c402c6cf4afefb5279bed2bc3e0fe Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 08:54:17 +0200 Subject: [PATCH 18/43] Add extra scopes and audience to token --- .../AudienceAuthority.java | 9 ++++ ...AuthorizationServerUserDetailsService.java | 47 ------------------- .../authorization_server/ScopeAuthority.java | 13 +++++ .../authorization_server/SecurityConfig.java | 18 +++---- .../oauth/rabbitmq.spring-oauth-provider.conf | 1 + 5 files changed, 29 insertions(+), 59 deletions(-) delete mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java index 74a33cb22403..e81cb774e089 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java @@ -1,5 +1,8 @@ package com.rabbitmq.authorization_server; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import java.util.List; + import org.springframework.security.core.GrantedAuthority; public class AudienceAuthority implements GrantedAuthority { @@ -20,4 +23,10 @@ public String getAuthority() { return authority; } + public static List getAll(AbstractAuthenticationToken principal) { + return principal.getAuthorities() + .stream().filter(a -> a instanceof AudienceAuthority) + .map(a -> a.getAuthority()).toList(); + } + } \ No newline at end of file diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java deleted file mode 100644 index d33f2963cdbe..000000000000 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AuthorizationServerUserDetailsService.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.rabbitmq.authorization_server; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import jakarta.annotation.PostConstruct; - -public class AuthorizationServerUserDetailsService implements UserDetailsService { - - private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationServerUserDetailsService.class); - - private final Map usersByUsername = new HashMap<>(); - - public AuthorizationServerUserDetailsService() { - - } - UserDetails ud; - - @PostConstruct - public void initUsers() { - List roles = List.of("openid", "profile", "rabbitmq.tag:administrator").stream().map(scope -> - new SimpleGrantedAuthority(scope)).toList(); - User rabbit_admin = new User("rabbit_admin", "rabbit_admin", roles); - - usersByUsername.put(rabbit_admin.getUsername(), rabbit_admin); - - LOGGER.info("Initialized users {}, {} and {}", rabbit_admin); - } - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - if (usersByUsername.containsKey(username)) { - LOGGER.info("Found user for {}", username); - return usersByUsername.get(username); - } else { - LOGGER.warn("No user found for {}", username); - throw new UsernameNotFoundException("No user found for " + username); - } - } -} \ No newline at end of file diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java index b863a625b3d6..0dc88edd322a 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java @@ -1,5 +1,9 @@ package com.rabbitmq.authorization_server; +import java.util.List; +import java.util.Set; + +import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; public class ScopeAuthority implements GrantedAuthority { @@ -18,5 +22,14 @@ public static ScopeAuthority scope(String value) { public String getAuthority() { return authority; } + + public static List getAllUnauthorized(AbstractAuthenticationToken principal, + Set authorized) { + return principal.getAuthorities() + .stream() + .filter(a -> a instanceof ScopeAuthority) + .filter(a -> !authorized.contains(a.getAuthority())) + .map(a -> a.getAuthority()).toList(); + } } \ No newline at end of file diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 080a3fc36011..7730ac59a221 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -11,24 +11,18 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.http.MediaType; +import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.oauth2.core.AuthorizationGrantType; -import org.springframework.security.oauth2.core.ClientAuthenticationMethod; -import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; -import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; -import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; -import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; -import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @@ -156,11 +150,11 @@ private static KeyPair generateRsaKey() { public OAuth2TokenCustomizer jwtTokenCustomizer() { return (context) -> { if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { - System.out.println("Principal: " + context.getPrincipal()); - System.out.println("Authorized scopes: " + context.getAuthorizedScopes()); - context.getClaims().claims((claims) -> { - claims.put("aud", "rabbitmq"); - }); + AbstractAuthenticationToken principal = context.getPrincipal(); + context.getClaims() + .audience(AudienceAuthority.getAll(principal)) + .claim("extra_scope", ScopeAuthority.getAllUnauthorized(principal, + context.getAuthorizedScopes())); } }; } diff --git a/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf b/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf index 704f479f62b2..f4a8b882de38 100644 --- a/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf +++ b/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf @@ -1,2 +1,3 @@ auth_oauth2.issuer = ${SPRING_URL} auth_oauth2.https.cacertfile = ${SPRING_CA_CERT} +auth_oauth2.additional_scopes_key = extra_scope From 444a06da31d0a998516b0e02cf7072c897c0f4af Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 09:45:20 +0200 Subject: [PATCH 19/43] Configure post logout url --- .../authorization-server/src/main/resources/application.yml | 2 ++ selenium/test/oauth/spring/application.yml | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index daafd5bf944d..6ae96f1245e8 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -43,6 +43,8 @@ spring: - none redirect-uris: - "https://localhost:15671/js/oidc-oauth/login-callback.html" + post-logout-redirect-uris: + - "https://localhost:15671/" scopes: - openid - profile diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index fd429d3980ce..b727d8fe8e5f 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -42,7 +42,9 @@ spring: client-authentication-methods: - none redirect-uris: - - "https://localhost:15671/js/oidc-oauth/login-callback.html" + - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/js/oidc-oauth/login-callback.html" + post-logout-redirect-uris: + - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}" scopes: - openid - profile From 1c3e62f99cfecf48e29cdba74e27cbf28ee1b51c Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 09:45:47 +0200 Subject: [PATCH 20/43] Bump up to 0.0.5 --- .github/workflows/authorization-server-make.yaml | 2 +- selenium/authorization-server/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index 1856c912cbc9..e714eef0bc35 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.4 + IMAGE_TAG: 0.0.5 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index 925062afd86e..6784af422029 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.4 + 0.0.5 authorization-server Authorization Server for Selenium From cd847fd091eafb5f731673a1b082e6da2655319d Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 09:55:55 +0200 Subject: [PATCH 21/43] Fix logout --- selenium/bin/components/spring | 2 +- selenium/test/oauth/spring/application.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring index 03c22f053d31..a16f18d85e0b 100755 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -1,6 +1,6 @@ #!/usr/bin/env bash -SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.4 +SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.5 ensure_spring() { if docker ps | grep spring &> /dev/null; then diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index b727d8fe8e5f..890a475a1d1a 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -44,7 +44,7 @@ spring: redirect-uris: - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/js/oidc-oauth/login-callback.html" post-logout-redirect-uris: - - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}" + - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/" scopes: - openid - profile From e9b958eed2af79dd503ab872257706bed231815a Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 10:32:26 +0200 Subject: [PATCH 22/43] Externalize user configuration --- .../authorization_server/SecurityConfig.java | 35 +------ .../SimpleCORSFilter.java | 9 +- .../UsersConfiguration.java | 93 +++++++++++++++++++ .../src/main/resources/application.yml | 9 ++ 4 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/UsersConfiguration.java diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 7730ac59a221..c2c8cbdc86ef 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -36,9 +36,6 @@ import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; -import static com.rabbitmq.authorization_server.ScopeAuthority.scope; -import static com.rabbitmq.authorization_server.AudienceAuthority.aud; - @Configuration @EnableWebSecurity public class SecurityConfig { @@ -88,38 +85,10 @@ public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) } @Bean - public UserDetailsService userDetailsService() { - UserDetails userDetails = User.withDefaultPasswordEncoder() - .username("rabbit_admin") - .password("rabbit_admin") - .authorities(List.of( - scope("openid"), - scope("profile"), - scope("rabbitmq.tag:administrator"), - aud("rabbitmq"))) - .build(); - - return new InMemoryUserDetailsManager(userDetails); + public UserDetailsService userDetailsService(UsersConfiguration users) { + return new InMemoryUserDetailsManager(users.getUserDetails()); } -/* - @Bean - public RegisteredClientRepository registeredClientRepository() { - RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString()) - .clientId("oidc-client") - .clientSecret("{noop}secret") - .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) - .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) - .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) - .redirectUri("http://127.0.0.1:8080/login/oauth2/code/oidc-client") - .postLogoutRedirectUri("http://127.0.0.1:8080/") - .scope(OidcScopes.OPENID) - .scope(OidcScopes.PROFILE) - .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()) - .build(); - return new InMemoryRegisteredClientRepository(oidcClient); - } - */ @Bean public JWKSource jwkSource() { KeyPair keyPair = generateRsaKey(); diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java index af07557665e0..08c8e102511f 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SimpleCORSFilter.java @@ -1,11 +1,7 @@ package com.rabbitmq.authorization_server; import java.io.IOException; -import java.util.Optional; -import java.util.Set; - import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -29,13 +25,12 @@ public SimpleCORSFilter() { @Override public void init(FilterConfig fc) throws ServletException { - System.out.println("Init SimpleCORSFilter"); + } @Override public void doFilter(ServletRequest req, ServletResponse resp, - FilterChain chain) throws IOException, ServletException { - System.out.println("doFilter SimpleCORSFilter"); + FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) resp; HttpServletRequest request = (HttpServletRequest) req; response.setHeader("Access-Control-Allow-Origin", "*"); diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/UsersConfiguration.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/UsersConfiguration.java new file mode 100644 index 000000000000..c567fcb874aa --- /dev/null +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/UsersConfiguration.java @@ -0,0 +1,93 @@ +package com.rabbitmq.authorization_server; + +import java.util.List; +import java.util.stream.Stream; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import static com.rabbitmq.authorization_server.AudienceAuthority.aud; +import static com.rabbitmq.authorization_server.ScopeAuthority.scope; + +@Component +@ConfigurationProperties(prefix = "spring.security.oauth2") +public class UsersConfiguration { + + private List users; + + public UsersConfiguration() { + } + + @Override + public String toString() { + return "UsersConfiguration [users=" + users + "]"; + } + + public List getUserDetails() { + return users.stream().map(u -> + User.withDefaultPasswordEncoder() + .username(u.getUsername()) + .password(u.getPassword()) + .authorities(u.getAuthorities()) + .build()).toList(); + } + + public static class ConfigUser { + + private String username; + private String password; + private List scopes; + private List audiencies; + + public ConfigUser() { + } + + public void setUsername(String username) { + this.username = username; + } + public void setPassword(String password) { + this.password = password; + } + public void setScopes(List scopes) { + this.scopes = scopes; + } + public void setAudiencies(List audiencies) { + this.audiencies = audiencies; + } + public String getUsername() { + return username; + } + public String getPassword() { + return password; + } + public List getScopes() { + return scopes; + } + public List getAudiencies() { + return audiencies; + } + public List getAuthorities() { + return Stream.concat(scopes.stream().map(s -> scope(s)), + audiencies.stream().map(s -> aud(s))).toList(); + } + + @Override + public String toString() { + return "User [username=" + username + ", password=" + password + ", scopes=" + scopes + ", audiencies=" + + audiencies + "]"; + } + + + } + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } +} diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index 6ae96f1245e8..589de0660eb2 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -17,6 +17,15 @@ spring: type: PKCS12 security: oauth2: + users: + - username: rabbit_admin + password: rabbit_admin + scopes: + - openid + - profile + - rabbitmq.tag:administrator + audiencies: + - rabbitmq authorizationserver: client: mgt_api_client: From 8137723e6230e5acfe73320a74edea4622f278a6 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 10:33:27 +0200 Subject: [PATCH 23/43] Bump to 0.0.6 --- .github/workflows/authorization-server-make.yaml | 2 +- selenium/authorization-server/pom.xml | 2 +- .../src/main/resources/application.properties | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 selenium/authorization-server/src/main/resources/application.properties diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index e714eef0bc35..eca18ea38a80 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.5 + IMAGE_TAG: 0.0.6 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index 6784af422029..d31091878a8a 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.5 + 0.0.6 authorization-server Authorization Server for Selenium diff --git a/selenium/authorization-server/src/main/resources/application.properties b/selenium/authorization-server/src/main/resources/application.properties deleted file mode 100644 index 53b0187e0a8c..000000000000 --- a/selenium/authorization-server/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=authorization-server From 730285288fff65a967a5cca4af1dfdc9421215dc Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 10:33:53 +0200 Subject: [PATCH 24/43] Bump to 0.0.6 --- selenium/bin/components/spring | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring index a16f18d85e0b..829836dca5fe 100755 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -1,6 +1,6 @@ #!/usr/bin/env bash -SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.5 +SPRING_DOCKER_IMAGE=pivotalrabbitmq/spring-authorization-server:0.0.6 ensure_spring() { if docker ps | grep spring &> /dev/null; then From 075c6c64271aaa051a0f8c3fb5d55aad726fb3c6 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 13:46:54 +0200 Subject: [PATCH 25/43] Use TEST_CONFIG_PATH to determine SPRING_CONFIG_DIR --- selenium/bin/components/spring | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring index 829836dca5fe..196cf4c91372 100755 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -10,8 +10,7 @@ ensure_spring() { fi } init_spring() { - SPRING_CONFIG_PATH=${SPRING_CONFIG_PATH:-oauth/spring} - SPRING_CONFIG_DIR=$(realpath ${TEST_DIR}/${SPRING_CONFIG_PATH}) + SPRING_CONFIG_DIR=${TEST_CONFIG_PATH}/spring SPRING_URL=${SPRING_URL:-OAUTH_PROVIDER_URL} print "> SPRING_CONFIG_DIR: ${SPRING_CONFIG_DIR}" From 1b08b0c03ba0ebcfe8df9866401059b1c8933a35 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 13:48:47 +0200 Subject: [PATCH 26/43] First changes to test opaque tokens --- .../src/main/resources/application.yml | 3 +++ .../auth-oauth-backend-with-opaque-tokens.sh | 9 ++++++++ .../env.auth-oauth-spring.docker | 2 ++ .../rabbitmq.auth_backends-oauth-opaque.conf | 23 +++++++++++++++++++ selenium/test/oauth/spring/application.yml | 15 +++++++++--- 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100755 selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh create mode 100644 selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker create mode 100644 selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth-opaque.conf diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index 589de0660eb2..08984436e8a5 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -37,6 +37,8 @@ spring: client-authentication-methods: - client_secret_basic require-proof-key: true + token-settings: + access-token-format: reference scopes: - openid - profile @@ -48,6 +50,7 @@ spring: client-id: rabbitmq_client_code authorization-grant-types: - authorization_code + require-proof-key: true client-authentication-methods: - none redirect-uris: diff --git a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh new file mode 100755 index 000000000000..53e517e2007d --- /dev/null +++ b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +TEST_CASES_PATH=/authnz-msg-protocols +PROFILES="spring oauth-prodproducer auth-oauth-spring auth_backends-oauth-opaque " + +source $SCRIPT/../../bin/suite_template +runWith spring diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker new file mode 100644 index 000000000000..52d51a91af04 --- /dev/null +++ b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker @@ -0,0 +1,2 @@ +export OAUTH_PROVIDER_URL=https://spring:8443/ +export OAUTH_NODE_EXTRA_CA_CERTS=multi-oauth/devkeycloak/ca_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth-opaque.conf b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth-opaque.conf new file mode 100644 index 000000000000..d55bd163baa8 --- /dev/null +++ b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth-opaque.conf @@ -0,0 +1,23 @@ +## RabbitMQ configuration with 2 oauth2 resources, rabbit_prod and rabbit_dev, +## rather than a single resource_server_id +## Also, each resource is owned by its own oauth provider, i.e. RabbitMQ is +## accessed by users and clients from two different providers using their dedicated +## resource_server_id. +log.console.level = debug + +auth_backends.1 = rabbit_auth_backend_oauth2 + +# Common auth_oauth2 settings for all resources +auth_oauth2.preferred_username_claims.1 = preferred_username +auth_oauth2.preferred_username_claims.2 = user_name +auth_oauth2.preferred_username_claims.3 = email + +## Resource servers hosted by this rabbitmq instance +auth_oauth2.resource_servers.1.id = rabbitmq +auth_oauth2.resource_servers.1.oauth_provider_id = spring + +## Oauth providers +auth_oauth2.oauth_providers.spring.issuer = ${SPRING_URL} +auth_oauth2.oauth_providers.spring.https.cacertfile = ${SPRING_CA_CERT} +auth_oauth2.oauth_providers.spring.https.verify = verify_peer +auth_oauth2.oauth_providers.spring.https.hostname_verification = wildcard diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml index 890a475a1d1a..2ba5ad61a80c 100644 --- a/selenium/test/oauth/spring/application.yml +++ b/selenium/test/oauth/spring/application.yml @@ -17,6 +17,15 @@ spring: type: PKCS12 security: oauth2: + users: + - username: rabbit_admin + password: rabbit_admin + scopes: + - openid + - profile + - rabbitmq.tag:administrator + audiencies: + - rabbitmq authorizationserver: client: mgt_api_client: @@ -27,7 +36,8 @@ spring: - client_credentials client-authentication-methods: - client_secret_basic - require-proof-key: true + token-settings: + access-token-format: reference scopes: - openid - profile @@ -37,6 +47,7 @@ spring: registration: provider: spring client-id: rabbitmq_client_code + require-proof-key: true authorization-grant-types: - authorization_code client-authentication-methods: @@ -51,5 +62,3 @@ spring: - rabbitmq.tag:administrator - rabbitmq.tag:management client-name: rabbitmq_client_code - - \ No newline at end of file From ec704556b700475bf274d9f176622650737818fb Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 13 Jun 2025 14:12:20 +0200 Subject: [PATCH 27/43] Configure authz-messaging to test opaque tokens --- .../auth-oauth-backend-with-opaque-tokens.sh | 2 +- .../authnz-messaging/spring/application.yml | 38 +++++++++++++++++++ .../authnz-messaging/spring/openssl.cnf.in | 3 ++ .../env.auth-oauth-spring | 2 + .../env.auth-oauth-spring.docker | 2 - .../authnz-msg-protocols/env.oauth-producer | 2 + 6 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 selenium/suites/authnz-messaging/spring/application.yml create mode 100644 selenium/suites/authnz-messaging/spring/openssl.cnf.in create mode 100644 selenium/test/authnz-msg-protocols/env.auth-oauth-spring delete mode 100644 selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker create mode 100644 selenium/test/authnz-msg-protocols/env.oauth-producer diff --git a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh index 53e517e2007d..59e7ef7774cf 100755 --- a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh +++ b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="spring oauth-prodproducer auth-oauth-spring auth_backends-oauth-opaque " +PROFILES="spring oauth-producer auth-oauth-spring auth_backends-oauth-opaque " source $SCRIPT/../../bin/suite_template runWith spring diff --git a/selenium/suites/authnz-messaging/spring/application.yml b/selenium/suites/authnz-messaging/spring/application.yml new file mode 100644 index 000000000000..a6fc13dfde53 --- /dev/null +++ b/selenium/suites/authnz-messaging/spring/application.yml @@ -0,0 +1,38 @@ +server: + port: 8443 + ssl: + bundle: spring-authorizationserver + +spring: + ssl: + bundle: + jks: + spring-authorizationserver: + key: + alias: server-spring-tls + password: foobar + keystore: + location: /config/server_spring.jks + password: foobar + type: PKCS12 + security: + oauth2: + authorizationserver: + client: + producer: + registration: + provider: spring + client-id: producer + client-secret: producer + authorization-grant-types: + - client_credentials + client-authentication-methods: + - client_secret_basic + token-settings: + access-token-format: reference + scopes: + - rabbitmq.configure:*/* + - rabbitmq.read:*/* + - rabbitmq.write:*/* + client-name: producer + \ No newline at end of file diff --git a/selenium/suites/authnz-messaging/spring/openssl.cnf.in b/selenium/suites/authnz-messaging/spring/openssl.cnf.in new file mode 100644 index 000000000000..5ac3282046c5 --- /dev/null +++ b/selenium/suites/authnz-messaging/spring/openssl.cnf.in @@ -0,0 +1,3 @@ +[ client_alt_names ] +email.1 = rabbit_client@localhost +URI.1 = rabbit_client_id_uri diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring new file mode 100644 index 000000000000..045c9c3c9e48 --- /dev/null +++ b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring @@ -0,0 +1,2 @@ +export OAUTH_PROVIDER_URL=https://spring:8443/ +export OAUTH_NODE_EXTRA_CA_CERTS=spring/ca_spring_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker deleted file mode 100644 index 52d51a91af04..000000000000 --- a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker +++ /dev/null @@ -1,2 +0,0 @@ -export OAUTH_PROVIDER_URL=https://spring:8443/ -export OAUTH_NODE_EXTRA_CA_CERTS=multi-oauth/devkeycloak/ca_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/env.oauth-producer b/selenium/test/authnz-msg-protocols/env.oauth-producer new file mode 100644 index 000000000000..e33fbe63a0d9 --- /dev/null +++ b/selenium/test/authnz-msg-protocols/env.oauth-producer @@ -0,0 +1,2 @@ +export OAUTH_CLIENT_ID=producer +export OAUTH_CLIENT_SECRET=producer From cc49075bb14229a377a5661afd9a0a3fb5bf819f Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Mon, 16 Jun 2025 15:46:47 +0200 Subject: [PATCH 28/43] Use spring to test oauth2 in messaging protocols --- selenium/bin/components/spring | 2 +- .../env.auth-oauth-spring | 4 +- .../spring/application.yml | 64 +++++++++++++++++++ .../spring/openssl.cnf.in | 3 + 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 selenium/test/authnz-msg-protocols/spring/application.yml create mode 100644 selenium/test/authnz-msg-protocols/spring/openssl.cnf.in diff --git a/selenium/bin/components/spring b/selenium/bin/components/spring index 196cf4c91372..d7f2b2c88d34 100755 --- a/selenium/bin/components/spring +++ b/selenium/bin/components/spring @@ -11,7 +11,7 @@ ensure_spring() { } init_spring() { SPRING_CONFIG_DIR=${TEST_CONFIG_PATH}/spring - SPRING_URL=${SPRING_URL:-OAUTH_PROVIDER_URL} + SPRING_URL=${SPRING_URL:-$OAUTH_PROVIDER_URL} print "> SPRING_CONFIG_DIR: ${SPRING_CONFIG_DIR}" print "> SPRING_URL: ${SPRING_URL}" diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring index 045c9c3c9e48..90ab88e31a73 100644 --- a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring +++ b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring @@ -1,2 +1,4 @@ +export SPRING_URL=https://spring:8443/ export OAUTH_PROVIDER_URL=https://spring:8443/ -export OAUTH_NODE_EXTRA_CA_CERTS=spring/ca_spring_certificate.pem +export SPRING_CA_CERT=/config/ca_spring_certificate.pem +export OAUTH_NODE_EXTRA_CA_CERTS=/config/ca_spring_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/spring/application.yml b/selenium/test/authnz-msg-protocols/spring/application.yml new file mode 100644 index 000000000000..2ba5ad61a80c --- /dev/null +++ b/selenium/test/authnz-msg-protocols/spring/application.yml @@ -0,0 +1,64 @@ +server: + port: 8443 + ssl: + bundle: spring-authorizationserver + +spring: + ssl: + bundle: + jks: + spring-authorizationserver: + key: + alias: server-spring-tls + password: foobar + keystore: + location: /config/server_spring.jks + password: foobar + type: PKCS12 + security: + oauth2: + users: + - username: rabbit_admin + password: rabbit_admin + scopes: + - openid + - profile + - rabbitmq.tag:administrator + audiencies: + - rabbitmq + authorizationserver: + client: + mgt_api_client: + registration: + provider: spring + client-id: mgt_api_client + authorization-grant-types: + - client_credentials + client-authentication-methods: + - client_secret_basic + token-settings: + access-token-format: reference + scopes: + - openid + - profile + - rabbitmq.tag:management + client-name: mgt_api_client + rabbitmq_client_code: + registration: + provider: spring + client-id: rabbitmq_client_code + require-proof-key: true + authorization-grant-types: + - authorization_code + client-authentication-methods: + - none + redirect-uris: + - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/js/oidc-oauth/login-callback.html" + post-logout-redirect-uris: + - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/" + scopes: + - openid + - profile + - rabbitmq.tag:administrator + - rabbitmq.tag:management + client-name: rabbitmq_client_code diff --git a/selenium/test/authnz-msg-protocols/spring/openssl.cnf.in b/selenium/test/authnz-msg-protocols/spring/openssl.cnf.in new file mode 100644 index 000000000000..5ac3282046c5 --- /dev/null +++ b/selenium/test/authnz-msg-protocols/spring/openssl.cnf.in @@ -0,0 +1,3 @@ +[ client_alt_names ] +email.1 = rabbit_client@localhost +URI.1 = rabbit_client_id_uri From a9eaf4c13f4af7a187e50b964c0e32b37a7819fe Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Tue, 17 Jun 2025 11:37:38 +0200 Subject: [PATCH 29/43] Fix some issues to obtain a token using client_credentials with spring --- .../auth-oauth-backend-with-opaque-tokens.sh | 2 +- ...th-oauth-spring => env.auth-oauth-spring.docker} | 4 ++-- .../env.auth-oauth-spring.local | 4 ++++ .../test/authnz-msg-protocols/env.oauth-producer | 1 + selenium/test/authnz-msg-protocols/mqtt.js | 3 ++- ...oauth.conf => rabbitmq.auth_backends-oauth.conf} | 0 ...onf => rabbitmq.auth_backends-opaque-oauth.conf} | 6 +----- .../authnz-msg-protocols/spring/application.yml | 13 +++++++------ 8 files changed, 18 insertions(+), 15 deletions(-) rename selenium/test/authnz-msg-protocols/{env.auth-oauth-spring => env.auth-oauth-spring.docker} (58%) create mode 100644 selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local rename selenium/test/authnz-msg-protocols/{rabbitmq.backends-oauth.conf => rabbitmq.auth_backends-oauth.conf} (100%) rename selenium/test/authnz-msg-protocols/{rabbitmq.auth_backends-oauth-opaque.conf => rabbitmq.auth_backends-opaque-oauth.conf} (70%) diff --git a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh index 59e7ef7774cf..d7915d9a2c72 100755 --- a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh +++ b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="spring oauth-producer auth-oauth-spring auth_backends-oauth-opaque " +PROFILES="spring oauth-producer auth-oauth-spring auth_backends-opaque-oauth auth-mtls" source $SCRIPT/../../bin/suite_template runWith spring diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker similarity index 58% rename from selenium/test/authnz-msg-protocols/env.auth-oauth-spring rename to selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker index 90ab88e31a73..d683a2ba0d53 100644 --- a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring +++ b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker @@ -1,4 +1,4 @@ -export SPRING_URL=https://spring:8443/ -export OAUTH_PROVIDER_URL=https://spring:8443/ +export SPRING_URL=https://spring:8443 +export OAUTH_PROVIDER_URL=https://spring:8443 export SPRING_CA_CERT=/config/ca_spring_certificate.pem export OAUTH_NODE_EXTRA_CA_CERTS=/config/ca_spring_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local new file mode 100644 index 000000000000..ad40cbe9b577 --- /dev/null +++ b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local @@ -0,0 +1,4 @@ +export SPRING_URL=https://localhost:8443 +export OAUTH_PROVIDER_URL=https://localhost:8443 +export SPRING_CA_CERT=authnz-msg-protocols/spring/ca_spring_certificate.pem +export OAUTH_NODE_EXTRA_CA_CERTS=authnz-msg-protocols/spring/ca_spring_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/env.oauth-producer b/selenium/test/authnz-msg-protocols/env.oauth-producer index e33fbe63a0d9..d0e99a18c626 100644 --- a/selenium/test/authnz-msg-protocols/env.oauth-producer +++ b/selenium/test/authnz-msg-protocols/env.oauth-producer @@ -1,2 +1,3 @@ +export RABBITMQ_AMQP_USERNAME=oauth export OAUTH_CLIENT_ID=producer export OAUTH_CLIENT_SECRET=producer diff --git a/selenium/test/authnz-msg-protocols/mqtt.js b/selenium/test/authnz-msg-protocols/mqtt.js index c6466a919d5a..81a008b8f01d 100644 --- a/selenium/test/authnz-msg-protocols/mqtt.js +++ b/selenium/test/authnz-msg-protocols/mqtt.js @@ -44,8 +44,9 @@ describe('Having MQTT protocol enbled and the following auth_backends: ' + backe let oauthProviderUrl = process.env.OAUTH_PROVIDER_URL let oauthClientId = process.env.OAUTH_CLIENT_ID let oauthClientSecret = process.env.OAUTH_CLIENT_SECRET + log("Obtening OpenId configuration from " + oauthProviderUrl) let openIdConfig = openIdConfiguration(oauthProviderUrl) - log("Obtained token_endpoint : " + openIdConfig.token_endpoint) + log("Obtaining token from " + openIdConfig.token_endpoint + " using " + oauthClientId + ":" + oauthClientSecret) password = tokenFor(oauthClientId, oauthClientSecret, openIdConfig.token_endpoint) log("Obtained access token : " + password) } diff --git a/selenium/test/authnz-msg-protocols/rabbitmq.backends-oauth.conf b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth.conf similarity index 100% rename from selenium/test/authnz-msg-protocols/rabbitmq.backends-oauth.conf rename to selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth.conf diff --git a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth-opaque.conf b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf similarity index 70% rename from selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth-opaque.conf rename to selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf index d55bd163baa8..7f4f6b4c3b45 100644 --- a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth-opaque.conf +++ b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf @@ -1,8 +1,4 @@ -## RabbitMQ configuration with 2 oauth2 resources, rabbit_prod and rabbit_dev, -## rather than a single resource_server_id -## Also, each resource is owned by its own oauth provider, i.e. RabbitMQ is -## accessed by users and clients from two different providers using their dedicated -## resource_server_id. + log.console.level = debug auth_backends.1 = rabbit_auth_backend_oauth2 diff --git a/selenium/test/authnz-msg-protocols/spring/application.yml b/selenium/test/authnz-msg-protocols/spring/application.yml index 2ba5ad61a80c..d78008a5a705 100644 --- a/selenium/test/authnz-msg-protocols/spring/application.yml +++ b/selenium/test/authnz-msg-protocols/spring/application.yml @@ -28,21 +28,22 @@ spring: - rabbitmq authorizationserver: client: - mgt_api_client: + producer: registration: provider: spring - client-id: mgt_api_client + client-id: producer + client-secret: "{noop}producer" authorization-grant-types: - client_credentials client-authentication-methods: - - client_secret_basic - token-settings: - access-token-format: reference + - client_secret_post +# token-settings: +# access-token-format: reference scopes: - openid - profile - rabbitmq.tag:management - client-name: mgt_api_client + client-name: producer rabbitmq_client_code: registration: provider: spring From eeae3af868ed95020f91ea6353a79f6217000c29 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Tue, 17 Jun 2025 13:06:57 +0200 Subject: [PATCH 30/43] Obtained jwt token from spring auth server Pendind to obtain an opaque --- .../authorization_server/SecurityConfig.java | 7 ++++--- .../src/main/resources/application.yml | 17 ++++++++++------- .../auth-cache-http-backends.sh | 2 +- .../auth-cache-ldap-backends.sh | 2 +- .../auth-http-backend-with-mtls.sh | 2 +- ...th-http-internal-backends-with-internal.sh | 2 +- .../auth-http-internal-backends.sh | 2 +- .../authnz-messaging/auth-internal-backend.sh | 2 +- .../auth-internal-http-backends.sh | 2 +- .../auth-internal-mtls-backend.sh | 2 +- .../authnz-messaging/auth-ldap-backend.sh | 2 +- .../auth-oauth-backend-with-opaque-tokens.sh | 2 +- .../{env.http-user => env.amqp-http-user} | 0 ...v.internal-user => env.amqp-internal-user} | 1 + .../{env.ldap-user => env.amqp-ldap-user} | 0 .../env.auth-oauth-spring.local | 2 +- selenium/test/authnz-msg-protocols/mqtt.js | 4 ++-- .../rabbitmq.auth_backends-opaque-oauth.conf | 19 ++++++++----------- .../spring/application.yml | 3 +++ selenium/test/utils.js | 8 +++++--- 20 files changed, 44 insertions(+), 37 deletions(-) rename selenium/test/authnz-msg-protocols/{env.http-user => env.amqp-http-user} (100%) rename selenium/test/authnz-msg-protocols/{env.internal-user => env.amqp-internal-user} (66%) rename selenium/test/authnz-msg-protocols/{env.ldap-user => env.amqp-ldap-user} (100%) diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index c2c8cbdc86ef..0227544477b8 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -4,7 +4,6 @@ import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; -import java.util.List; import java.util.UUID; import org.springframework.context.annotation.Bean; @@ -15,8 +14,6 @@ import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; @@ -120,6 +117,10 @@ public OAuth2TokenCustomizer jwtTokenCustomizer() { return (context) -> { if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { AbstractAuthenticationToken principal = context.getPrincipal(); + System.out.println("registered client: " + context.getRegisteredClient()); + System.out.println("authorities : " + principal.getAuthorities()); + System.out.println("authorized scopes : " + context.getAuthorizedScopes()); + context.getClaims() .audience(AudienceAuthority.getAll(principal)) .claim("extra_scope", ScopeAuthority.getAllUnauthorized(principal, diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index 08984436e8a5..92a8c9631e75 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -12,7 +12,7 @@ spring: alias: server-spring-tls password: foobar keystore: - location: ../test/oauth/spring/server_spring.jks + location: ../test/authnz-msg-protocols/spring/server_spring.jks password: foobar type: PKCS12 security: @@ -28,22 +28,25 @@ spring: - rabbitmq authorizationserver: client: - mgt_api_client: + producer: registration: provider: spring - client-id: mgt_api_client + client-id: producer + client-secret: "{noop}producer" authorization-grant-types: - client_credentials client-authentication-methods: - - client_secret_basic - require-proof-key: true + - client_secret_post token-settings: - access-token-format: reference + access-token-format: reference scopes: - openid - profile - rabbitmq.tag:management - client-name: mgt_api_client + - rabbitmq.configure:*/* + - rabbitmq.read:*/* + - rabbitmq.write:*/* + client-name: producer rabbitmq_client_code: registration: provider: spring diff --git a/selenium/suites/authnz-messaging/auth-cache-http-backends.sh b/selenium/suites/authnz-messaging/auth-cache-http-backends.sh index dba2c2710d93..e56e17bb9cc6 100755 --- a/selenium/suites/authnz-messaging/auth-cache-http-backends.sh +++ b/selenium/suites/authnz-messaging/auth-cache-http-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="http-user auth-http auth_backends-cache-http " +PROFILES="amqp-http-user auth-http auth_backends-cache-http " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh b/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh index 5be7e8a62774..f81d3cf75efe 100755 --- a/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh +++ b/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="ldap-user auth-ldap auth_backends-cache-ldap" +PROFILES="amqp-ldap-user auth-ldap auth_backends-cache-ldap" source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-ldap diff --git a/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh b/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh index 47245df83a69..e49275f3c54f 100755 --- a/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh +++ b/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="internal-user auth-http auth_backends-http auth-mtls" +PROFILES="amqp-internal-user auth-http auth_backends-http auth-mtls" # internal-user profile is used because the client certificates to # access rabbitmq are issued with the alt_name = internal-user diff --git a/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh b/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh index c7fb154b60bc..5fd016b2dc91 100755 --- a/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh +++ b/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="internal-user auth-http auth_backends-http-internal " +PROFILES="amqp-internal-user auth-http auth_backends-http-internal " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-http-internal-backends.sh b/selenium/suites/authnz-messaging/auth-http-internal-backends.sh index 105926e117dc..2b4b5f290a83 100755 --- a/selenium/suites/authnz-messaging/auth-http-internal-backends.sh +++ b/selenium/suites/authnz-messaging/auth-http-internal-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="http-user auth-http auth_backends-http-internal " +PROFILES="amqp-http-user auth-http auth_backends-http-internal " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-internal-backend.sh b/selenium/suites/authnz-messaging/auth-internal-backend.sh index b513001e1f6c..804b579f55ef 100755 --- a/selenium/suites/authnz-messaging/auth-internal-backend.sh +++ b/selenium/suites/authnz-messaging/auth-internal-backend.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="internal-user auth_backends-internal" +PROFILES="amqp-internal-user auth_backends-internal" source $SCRIPT/../../bin/suite_template run diff --git a/selenium/suites/authnz-messaging/auth-internal-http-backends.sh b/selenium/suites/authnz-messaging/auth-internal-http-backends.sh index ae44cf8e8dc6..221a32ef06ab 100755 --- a/selenium/suites/authnz-messaging/auth-internal-http-backends.sh +++ b/selenium/suites/authnz-messaging/auth-internal-http-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="internal-user auth_http auth_backends-internal-http " +PROFILES="amqp-internal-user auth_http auth_backends-internal-http " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh b/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh index df92f9d9cd43..687f7f269b18 100755 --- a/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh +++ b/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="internal-user auth_backends-internal tls auth-mtls" +PROFILES="amqp-internal-user auth_backends-internal tls auth-mtls" source $SCRIPT/../../bin/suite_template run diff --git a/selenium/suites/authnz-messaging/auth-ldap-backend.sh b/selenium/suites/authnz-messaging/auth-ldap-backend.sh index 8ecc52cc1dab..387633ccbfc2 100755 --- a/selenium/suites/authnz-messaging/auth-ldap-backend.sh +++ b/selenium/suites/authnz-messaging/auth-ldap-backend.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="ldap-user auth-ldap auth_backends-ldap " +PROFILES="amqp-ldap-user auth-ldap auth_backends-ldap " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-ldap diff --git a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh index d7915d9a2c72..f9c2b8c95e7a 100755 --- a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh +++ b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="spring oauth-producer auth-oauth-spring auth_backends-opaque-oauth auth-mtls" +PROFILES="spring oauth-producer auth-oauth-spring auth_backends-opaque-oauth " source $SCRIPT/../../bin/suite_template runWith spring diff --git a/selenium/test/authnz-msg-protocols/env.http-user b/selenium/test/authnz-msg-protocols/env.amqp-http-user similarity index 100% rename from selenium/test/authnz-msg-protocols/env.http-user rename to selenium/test/authnz-msg-protocols/env.amqp-http-user diff --git a/selenium/test/authnz-msg-protocols/env.internal-user b/selenium/test/authnz-msg-protocols/env.amqp-internal-user similarity index 66% rename from selenium/test/authnz-msg-protocols/env.internal-user rename to selenium/test/authnz-msg-protocols/env.amqp-internal-user index b35a68de7b3d..44e4e2f27918 100644 --- a/selenium/test/authnz-msg-protocols/env.internal-user +++ b/selenium/test/authnz-msg-protocols/env.amqp-internal-user @@ -1,2 +1,3 @@ export RABBITMQ_AMQP_USERNAME=internaluser export RABBITMQ_AMQP_PASSWORD=management +export RABBITMQ_MQTT_CLIENT_ID=internaluser \ No newline at end of file diff --git a/selenium/test/authnz-msg-protocols/env.ldap-user b/selenium/test/authnz-msg-protocols/env.amqp-ldap-user similarity index 100% rename from selenium/test/authnz-msg-protocols/env.ldap-user rename to selenium/test/authnz-msg-protocols/env.amqp-ldap-user diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local index ad40cbe9b577..4653299091a4 100644 --- a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local +++ b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local @@ -1,4 +1,4 @@ export SPRING_URL=https://localhost:8443 export OAUTH_PROVIDER_URL=https://localhost:8443 -export SPRING_CA_CERT=authnz-msg-protocols/spring/ca_spring_certificate.pem +export SPRING_CA_CERT=${TEST_CONFIG_PATH}/spring/ca_spring_certificate.pem export OAUTH_NODE_EXTRA_CA_CERTS=authnz-msg-protocols/spring/ca_spring_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/mqtt.js b/selenium/test/authnz-msg-protocols/mqtt.js index 81a008b8f01d..07c5fe567992 100644 --- a/selenium/test/authnz-msg-protocols/mqtt.js +++ b/selenium/test/authnz-msg-protocols/mqtt.js @@ -21,7 +21,7 @@ describe('Having MQTT protocol enbled and the following auth_backends: ' + backe let mqttUrl = process.env.RABBITMQ_MQTT_URL || "mqtt://" + rabbit + ":1883" let username = process.env.RABBITMQ_AMQP_USERNAME let password = process.env.RABBITMQ_AMQP_PASSWORD - let client_id = process.env.RABBITMQ_AMQP_USERNAME || 'selenium-client' + let client_id = process.env.RABBITMQ_MQTT_CLIENT_ID || 'selenium-client' before(function () { if (backends.includes("http") && (username.includes("http") || usemtls)) { @@ -47,7 +47,7 @@ describe('Having MQTT protocol enbled and the following auth_backends: ' + backe log("Obtening OpenId configuration from " + oauthProviderUrl) let openIdConfig = openIdConfiguration(oauthProviderUrl) log("Obtaining token from " + openIdConfig.token_endpoint + " using " + oauthClientId + ":" + oauthClientSecret) - password = tokenFor(oauthClientId, oauthClientSecret, openIdConfig.token_endpoint) + password = tokenFor(oauthClientId, oauthClientSecret, openIdConfig.token_endpoint, "rabbitmq.configure:*/*") log("Obtained access token : " + password) } mqttOptions = { diff --git a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf index 7f4f6b4c3b45..e868884ab94c 100644 --- a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf +++ b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf @@ -4,16 +4,13 @@ log.console.level = debug auth_backends.1 = rabbit_auth_backend_oauth2 # Common auth_oauth2 settings for all resources -auth_oauth2.preferred_username_claims.1 = preferred_username -auth_oauth2.preferred_username_claims.2 = user_name -auth_oauth2.preferred_username_claims.3 = email +auth_oauth2.preferred_username_claims.1 = sub -## Resource servers hosted by this rabbitmq instance -auth_oauth2.resource_servers.1.id = rabbitmq -auth_oauth2.resource_servers.1.oauth_provider_id = spring +## Resource server hosted by this rabbitmq instance +auth_oauth2.resource_server_id = rabbitmq +auth_oauth2.verify_aud = false +auth_oauth2.issuer = ${SPRING_URL} +auth_oauth2.https.cacertfile = ${SPRING_CA_CERT} +auth_oauth2.https.verify = verify_peer +auth_oauth2.https.hostname_verification = wildcard -## Oauth providers -auth_oauth2.oauth_providers.spring.issuer = ${SPRING_URL} -auth_oauth2.oauth_providers.spring.https.cacertfile = ${SPRING_CA_CERT} -auth_oauth2.oauth_providers.spring.https.verify = verify_peer -auth_oauth2.oauth_providers.spring.https.hostname_verification = wildcard diff --git a/selenium/test/authnz-msg-protocols/spring/application.yml b/selenium/test/authnz-msg-protocols/spring/application.yml index d78008a5a705..ef21a66c87e9 100644 --- a/selenium/test/authnz-msg-protocols/spring/application.yml +++ b/selenium/test/authnz-msg-protocols/spring/application.yml @@ -43,6 +43,9 @@ spring: - openid - profile - rabbitmq.tag:management + - rabbitmq.configure:*/* + - rabbitmq.read:*/* + - rabbitmq.write:*/* client-name: producer rabbitmq_client_code: registration: diff --git a/selenium/test/utils.js b/selenium/test/utils.js index c862b290cc04..af88b9949dbd 100644 --- a/selenium/test/utils.js +++ b/selenium/test/utils.js @@ -236,14 +236,16 @@ module.exports = { } }, - tokenFor: (client_id, client_secret, url = uaaUrl) => { + tokenFor: (client_id, client_secret, url = uaaUrl, scopes = "") => { const req = new XMLHttpRequest() - const params = 'client_id=' + client_id + + let params = 'client_id=' + client_id + '&client_secret=' + client_secret + '&grant_type=client_credentials' + '&token_format=jwt' + '&response_type=token' - + if (scopes != "") { + params = params + "&scope=" + scopes + } req.open('POST', url, false) req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') req.setRequestHeader('Accept', 'application/json') From f7309cf5101a4c84d078ec21fc289dad9861a099 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Tue, 17 Jun 2025 13:52:46 +0200 Subject: [PATCH 31/43] Configure spring with opaque token Tests failing now until backend calls introspection endpoint --- .../com/rabbitmq/authorization_server/SecurityConfig.java | 2 ++ .../authorization-server/src/main/resources/application.yml | 6 +++--- selenium/suites/authnz-messaging/spring/application.yml | 4 ++-- selenium/test/utils.js | 1 - 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 0227544477b8..22dc8bf4349b 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -118,6 +118,8 @@ public OAuth2TokenCustomizer jwtTokenCustomizer() { if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { AbstractAuthenticationToken principal = context.getPrincipal(); System.out.println("registered client: " + context.getRegisteredClient()); + System.out.println("token format : " + + context.getRegisteredClient().getTokenSettings().getAccessTokenFormat().getValue()); System.out.println("authorities : " + principal.getAuthorities()); System.out.println("authorized scopes : " + context.getAuthorizedScopes()); diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index 92a8c9631e75..d45b72d3038c 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -36,9 +36,7 @@ spring: authorization-grant-types: - client_credentials client-authentication-methods: - - client_secret_post - token-settings: - access-token-format: reference + - client_secret_post scopes: - openid - profile @@ -47,6 +45,8 @@ spring: - rabbitmq.read:*/* - rabbitmq.write:*/* client-name: producer + token: + access-token-format: reference rabbitmq_client_code: registration: provider: spring diff --git a/selenium/suites/authnz-messaging/spring/application.yml b/selenium/suites/authnz-messaging/spring/application.yml index a6fc13dfde53..c950d36f64a8 100644 --- a/selenium/suites/authnz-messaging/spring/application.yml +++ b/selenium/suites/authnz-messaging/spring/application.yml @@ -28,11 +28,11 @@ spring: - client_credentials client-authentication-methods: - client_secret_basic - token-settings: - access-token-format: reference scopes: - rabbitmq.configure:*/* - rabbitmq.read:*/* - rabbitmq.write:*/* client-name: producer + token: + access-token-format: reference \ No newline at end of file diff --git a/selenium/test/utils.js b/selenium/test/utils.js index af88b9949dbd..7662699cf70c 100644 --- a/selenium/test/utils.js +++ b/selenium/test/utils.js @@ -241,7 +241,6 @@ module.exports = { let params = 'client_id=' + client_id + '&client_secret=' + client_secret + '&grant_type=client_credentials' + - '&token_format=jwt' + '&response_type=token' if (scopes != "") { params = params + "&scope=" + scopes From 07b68d6e31c4c6bfc6c3ae0560b48feb972cf4ca Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 18 Jun 2025 09:33:44 +0200 Subject: [PATCH 32/43] Moved changes to feature-8662 --- .../auth-cache-http-backends.sh | 2 +- .../auth-cache-ldap-backends.sh | 2 +- .../auth-http-backend-with-mtls.sh | 2 +- ...th-http-internal-backends-with-internal.sh | 2 +- .../auth-http-internal-backends.sh | 2 +- .../authnz-messaging/auth-internal-backend.sh | 2 +- .../auth-internal-http-backends.sh | 2 +- .../auth-internal-mtls-backend.sh | 2 +- .../authnz-messaging/auth-ldap-backend.sh | 2 +- .../auth-oauth-backend-with-opaque-tokens.sh | 9 --- .../authnz-messaging/spring/application.yml | 38 ----------- .../authnz-messaging/spring/openssl.cnf.in | 3 - .../suites/authnz-mgt/oauth-with-spring.sh | 10 --- .../env.auth-oauth-spring.docker | 4 -- .../env.auth-oauth-spring.local | 4 -- .../{env.amqp-http-user => env.http-user} | 0 ...v.amqp-internal-user => env.internal-user} | 1 - .../{env.amqp-ldap-user => env.ldap-user} | 0 .../authnz-msg-protocols/env.oauth-producer | 3 - selenium/test/authnz-msg-protocols/mqtt.js | 6 +- .../rabbitmq.auth_backends-opaque-oauth.conf | 16 ----- .../spring/application.yml | 68 ------------------- .../spring/openssl.cnf.in | 3 - selenium/test/oauth/env.docker.spring | 2 - selenium/test/oauth/env.local.spring | 3 - selenium/test/oauth/env.spring | 2 - selenium/test/oauth/env.spring-oauth-provider | 2 - selenium/test/oauth/spring/application.yml | 64 ----------------- selenium/test/oauth/spring/openssl.cnf.in | 3 - 29 files changed, 11 insertions(+), 248 deletions(-) delete mode 100755 selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh delete mode 100644 selenium/suites/authnz-messaging/spring/application.yml delete mode 100644 selenium/suites/authnz-messaging/spring/openssl.cnf.in delete mode 100755 selenium/suites/authnz-mgt/oauth-with-spring.sh delete mode 100644 selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker delete mode 100644 selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local rename selenium/test/authnz-msg-protocols/{env.amqp-http-user => env.http-user} (100%) rename selenium/test/authnz-msg-protocols/{env.amqp-internal-user => env.internal-user} (66%) rename selenium/test/authnz-msg-protocols/{env.amqp-ldap-user => env.ldap-user} (100%) delete mode 100644 selenium/test/authnz-msg-protocols/env.oauth-producer delete mode 100644 selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf delete mode 100644 selenium/test/authnz-msg-protocols/spring/application.yml delete mode 100644 selenium/test/authnz-msg-protocols/spring/openssl.cnf.in delete mode 100644 selenium/test/oauth/env.docker.spring delete mode 100644 selenium/test/oauth/env.local.spring delete mode 100644 selenium/test/oauth/env.spring delete mode 100644 selenium/test/oauth/env.spring-oauth-provider delete mode 100644 selenium/test/oauth/spring/application.yml delete mode 100644 selenium/test/oauth/spring/openssl.cnf.in diff --git a/selenium/suites/authnz-messaging/auth-cache-http-backends.sh b/selenium/suites/authnz-messaging/auth-cache-http-backends.sh index e56e17bb9cc6..dba2c2710d93 100755 --- a/selenium/suites/authnz-messaging/auth-cache-http-backends.sh +++ b/selenium/suites/authnz-messaging/auth-cache-http-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-http-user auth-http auth_backends-cache-http " +PROFILES="http-user auth-http auth_backends-cache-http " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh b/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh index f81d3cf75efe..5be7e8a62774 100755 --- a/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh +++ b/selenium/suites/authnz-messaging/auth-cache-ldap-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-ldap-user auth-ldap auth_backends-cache-ldap" +PROFILES="ldap-user auth-ldap auth_backends-cache-ldap" source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-ldap diff --git a/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh b/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh index e49275f3c54f..47245df83a69 100755 --- a/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh +++ b/selenium/suites/authnz-messaging/auth-http-backend-with-mtls.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-internal-user auth-http auth_backends-http auth-mtls" +PROFILES="internal-user auth-http auth_backends-http auth-mtls" # internal-user profile is used because the client certificates to # access rabbitmq are issued with the alt_name = internal-user diff --git a/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh b/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh index 5fd016b2dc91..c7fb154b60bc 100755 --- a/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh +++ b/selenium/suites/authnz-messaging/auth-http-internal-backends-with-internal.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-internal-user auth-http auth_backends-http-internal " +PROFILES="internal-user auth-http auth_backends-http-internal " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-http-internal-backends.sh b/selenium/suites/authnz-messaging/auth-http-internal-backends.sh index 2b4b5f290a83..105926e117dc 100755 --- a/selenium/suites/authnz-messaging/auth-http-internal-backends.sh +++ b/selenium/suites/authnz-messaging/auth-http-internal-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-http-user auth-http auth_backends-http-internal " +PROFILES="http-user auth-http auth_backends-http-internal " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-internal-backend.sh b/selenium/suites/authnz-messaging/auth-internal-backend.sh index 804b579f55ef..b513001e1f6c 100755 --- a/selenium/suites/authnz-messaging/auth-internal-backend.sh +++ b/selenium/suites/authnz-messaging/auth-internal-backend.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-internal-user auth_backends-internal" +PROFILES="internal-user auth_backends-internal" source $SCRIPT/../../bin/suite_template run diff --git a/selenium/suites/authnz-messaging/auth-internal-http-backends.sh b/selenium/suites/authnz-messaging/auth-internal-http-backends.sh index 221a32ef06ab..ae44cf8e8dc6 100755 --- a/selenium/suites/authnz-messaging/auth-internal-http-backends.sh +++ b/selenium/suites/authnz-messaging/auth-internal-http-backends.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-internal-user auth_http auth_backends-internal-http " +PROFILES="internal-user auth_http auth_backends-internal-http " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-http diff --git a/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh b/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh index 687f7f269b18..df92f9d9cd43 100755 --- a/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh +++ b/selenium/suites/authnz-messaging/auth-internal-mtls-backend.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-internal-user auth_backends-internal tls auth-mtls" +PROFILES="internal-user auth_backends-internal tls auth-mtls" source $SCRIPT/../../bin/suite_template run diff --git a/selenium/suites/authnz-messaging/auth-ldap-backend.sh b/selenium/suites/authnz-messaging/auth-ldap-backend.sh index 387633ccbfc2..8ecc52cc1dab 100755 --- a/selenium/suites/authnz-messaging/auth-ldap-backend.sh +++ b/selenium/suites/authnz-messaging/auth-ldap-backend.sh @@ -3,7 +3,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="amqp-ldap-user auth-ldap auth_backends-ldap " +PROFILES="ldap-user auth-ldap auth_backends-ldap " source $SCRIPT/../../bin/suite_template runWith mock-auth-backend-ldap diff --git a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh b/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh deleted file mode 100755 index f9c2b8c95e7a..000000000000 --- a/selenium/suites/authnz-messaging/auth-oauth-backend-with-opaque-tokens.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -TEST_CASES_PATH=/authnz-msg-protocols -PROFILES="spring oauth-producer auth-oauth-spring auth_backends-opaque-oauth " - -source $SCRIPT/../../bin/suite_template -runWith spring diff --git a/selenium/suites/authnz-messaging/spring/application.yml b/selenium/suites/authnz-messaging/spring/application.yml deleted file mode 100644 index c950d36f64a8..000000000000 --- a/selenium/suites/authnz-messaging/spring/application.yml +++ /dev/null @@ -1,38 +0,0 @@ -server: - port: 8443 - ssl: - bundle: spring-authorizationserver - -spring: - ssl: - bundle: - jks: - spring-authorizationserver: - key: - alias: server-spring-tls - password: foobar - keystore: - location: /config/server_spring.jks - password: foobar - type: PKCS12 - security: - oauth2: - authorizationserver: - client: - producer: - registration: - provider: spring - client-id: producer - client-secret: producer - authorization-grant-types: - - client_credentials - client-authentication-methods: - - client_secret_basic - scopes: - - rabbitmq.configure:*/* - - rabbitmq.read:*/* - - rabbitmq.write:*/* - client-name: producer - token: - access-token-format: reference - \ No newline at end of file diff --git a/selenium/suites/authnz-messaging/spring/openssl.cnf.in b/selenium/suites/authnz-messaging/spring/openssl.cnf.in deleted file mode 100644 index 5ac3282046c5..000000000000 --- a/selenium/suites/authnz-messaging/spring/openssl.cnf.in +++ /dev/null @@ -1,3 +0,0 @@ -[ client_alt_names ] -email.1 = rabbit_client@localhost -URI.1 = rabbit_client_id_uri diff --git a/selenium/suites/authnz-mgt/oauth-with-spring.sh b/selenium/suites/authnz-mgt/oauth-with-spring.sh deleted file mode 100755 index 583875f677d3..000000000000 --- a/selenium/suites/authnz-mgt/oauth-with-spring.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -TEST_CASES_PATH=/oauth/with-sp-initiated -TEST_CONFIG_PATH=/oauth -PROFILES="spring spring-oauth-provider tls" - -source $SCRIPT/../../bin/suite_template $@ -runWith spring diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker deleted file mode 100644 index d683a2ba0d53..000000000000 --- a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.docker +++ /dev/null @@ -1,4 +0,0 @@ -export SPRING_URL=https://spring:8443 -export OAUTH_PROVIDER_URL=https://spring:8443 -export SPRING_CA_CERT=/config/ca_spring_certificate.pem -export OAUTH_NODE_EXTRA_CA_CERTS=/config/ca_spring_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local b/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local deleted file mode 100644 index 4653299091a4..000000000000 --- a/selenium/test/authnz-msg-protocols/env.auth-oauth-spring.local +++ /dev/null @@ -1,4 +0,0 @@ -export SPRING_URL=https://localhost:8443 -export OAUTH_PROVIDER_URL=https://localhost:8443 -export SPRING_CA_CERT=${TEST_CONFIG_PATH}/spring/ca_spring_certificate.pem -export OAUTH_NODE_EXTRA_CA_CERTS=authnz-msg-protocols/spring/ca_spring_certificate.pem diff --git a/selenium/test/authnz-msg-protocols/env.amqp-http-user b/selenium/test/authnz-msg-protocols/env.http-user similarity index 100% rename from selenium/test/authnz-msg-protocols/env.amqp-http-user rename to selenium/test/authnz-msg-protocols/env.http-user diff --git a/selenium/test/authnz-msg-protocols/env.amqp-internal-user b/selenium/test/authnz-msg-protocols/env.internal-user similarity index 66% rename from selenium/test/authnz-msg-protocols/env.amqp-internal-user rename to selenium/test/authnz-msg-protocols/env.internal-user index 44e4e2f27918..b35a68de7b3d 100644 --- a/selenium/test/authnz-msg-protocols/env.amqp-internal-user +++ b/selenium/test/authnz-msg-protocols/env.internal-user @@ -1,3 +1,2 @@ export RABBITMQ_AMQP_USERNAME=internaluser export RABBITMQ_AMQP_PASSWORD=management -export RABBITMQ_MQTT_CLIENT_ID=internaluser \ No newline at end of file diff --git a/selenium/test/authnz-msg-protocols/env.amqp-ldap-user b/selenium/test/authnz-msg-protocols/env.ldap-user similarity index 100% rename from selenium/test/authnz-msg-protocols/env.amqp-ldap-user rename to selenium/test/authnz-msg-protocols/env.ldap-user diff --git a/selenium/test/authnz-msg-protocols/env.oauth-producer b/selenium/test/authnz-msg-protocols/env.oauth-producer deleted file mode 100644 index d0e99a18c626..000000000000 --- a/selenium/test/authnz-msg-protocols/env.oauth-producer +++ /dev/null @@ -1,3 +0,0 @@ -export RABBITMQ_AMQP_USERNAME=oauth -export OAUTH_CLIENT_ID=producer -export OAUTH_CLIENT_SECRET=producer diff --git a/selenium/test/authnz-msg-protocols/mqtt.js b/selenium/test/authnz-msg-protocols/mqtt.js index 07c5fe567992..d0a97825cd79 100644 --- a/selenium/test/authnz-msg-protocols/mqtt.js +++ b/selenium/test/authnz-msg-protocols/mqtt.js @@ -21,7 +21,7 @@ describe('Having MQTT protocol enbled and the following auth_backends: ' + backe let mqttUrl = process.env.RABBITMQ_MQTT_URL || "mqtt://" + rabbit + ":1883" let username = process.env.RABBITMQ_AMQP_USERNAME let password = process.env.RABBITMQ_AMQP_PASSWORD - let client_id = process.env.RABBITMQ_MQTT_CLIENT_ID || 'selenium-client' + let client_id = process.env.RABBITMQ_AMQP_USERNAME || 'selenium-client' before(function () { if (backends.includes("http") && (username.includes("http") || usemtls)) { @@ -44,10 +44,8 @@ describe('Having MQTT protocol enbled and the following auth_backends: ' + backe let oauthProviderUrl = process.env.OAUTH_PROVIDER_URL let oauthClientId = process.env.OAUTH_CLIENT_ID let oauthClientSecret = process.env.OAUTH_CLIENT_SECRET - log("Obtening OpenId configuration from " + oauthProviderUrl) let openIdConfig = openIdConfiguration(oauthProviderUrl) - log("Obtaining token from " + openIdConfig.token_endpoint + " using " + oauthClientId + ":" + oauthClientSecret) - password = tokenFor(oauthClientId, oauthClientSecret, openIdConfig.token_endpoint, "rabbitmq.configure:*/*") + password = tokenFor(oauthClientId, oauthClientSecret, openIdConfig.token_endpoint) log("Obtained access token : " + password) } mqttOptions = { diff --git a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf b/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf deleted file mode 100644 index e868884ab94c..000000000000 --- a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-opaque-oauth.conf +++ /dev/null @@ -1,16 +0,0 @@ - -log.console.level = debug - -auth_backends.1 = rabbit_auth_backend_oauth2 - -# Common auth_oauth2 settings for all resources -auth_oauth2.preferred_username_claims.1 = sub - -## Resource server hosted by this rabbitmq instance -auth_oauth2.resource_server_id = rabbitmq -auth_oauth2.verify_aud = false -auth_oauth2.issuer = ${SPRING_URL} -auth_oauth2.https.cacertfile = ${SPRING_CA_CERT} -auth_oauth2.https.verify = verify_peer -auth_oauth2.https.hostname_verification = wildcard - diff --git a/selenium/test/authnz-msg-protocols/spring/application.yml b/selenium/test/authnz-msg-protocols/spring/application.yml deleted file mode 100644 index ef21a66c87e9..000000000000 --- a/selenium/test/authnz-msg-protocols/spring/application.yml +++ /dev/null @@ -1,68 +0,0 @@ -server: - port: 8443 - ssl: - bundle: spring-authorizationserver - -spring: - ssl: - bundle: - jks: - spring-authorizationserver: - key: - alias: server-spring-tls - password: foobar - keystore: - location: /config/server_spring.jks - password: foobar - type: PKCS12 - security: - oauth2: - users: - - username: rabbit_admin - password: rabbit_admin - scopes: - - openid - - profile - - rabbitmq.tag:administrator - audiencies: - - rabbitmq - authorizationserver: - client: - producer: - registration: - provider: spring - client-id: producer - client-secret: "{noop}producer" - authorization-grant-types: - - client_credentials - client-authentication-methods: - - client_secret_post -# token-settings: -# access-token-format: reference - scopes: - - openid - - profile - - rabbitmq.tag:management - - rabbitmq.configure:*/* - - rabbitmq.read:*/* - - rabbitmq.write:*/* - client-name: producer - rabbitmq_client_code: - registration: - provider: spring - client-id: rabbitmq_client_code - require-proof-key: true - authorization-grant-types: - - authorization_code - client-authentication-methods: - - none - redirect-uris: - - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/js/oidc-oauth/login-callback.html" - post-logout-redirect-uris: - - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/" - scopes: - - openid - - profile - - rabbitmq.tag:administrator - - rabbitmq.tag:management - client-name: rabbitmq_client_code diff --git a/selenium/test/authnz-msg-protocols/spring/openssl.cnf.in b/selenium/test/authnz-msg-protocols/spring/openssl.cnf.in deleted file mode 100644 index 5ac3282046c5..000000000000 --- a/selenium/test/authnz-msg-protocols/spring/openssl.cnf.in +++ /dev/null @@ -1,3 +0,0 @@ -[ client_alt_names ] -email.1 = rabbit_client@localhost -URI.1 = rabbit_client_id_uri diff --git a/selenium/test/oauth/env.docker.spring b/selenium/test/oauth/env.docker.spring deleted file mode 100644 index 78a0af0cc08a..000000000000 --- a/selenium/test/oauth/env.docker.spring +++ /dev/null @@ -1,2 +0,0 @@ -export SPRING_URL=https://spring:8443 -export SPRING_CA_CERT=/config/oauth/spring/ca_spring_certificate.pem diff --git a/selenium/test/oauth/env.local.spring b/selenium/test/oauth/env.local.spring deleted file mode 100644 index 20f8c16cd943..000000000000 --- a/selenium/test/oauth/env.local.spring +++ /dev/null @@ -1,3 +0,0 @@ -export SPRING_URL=https://localhost:8443 -export OAUTH_PROVIDER_URL=${SPRING_URL} -export SPRING_CA_CERT=selenium/test/oauth/spring/ca_spring_certificate.pem diff --git a/selenium/test/oauth/env.spring b/selenium/test/oauth/env.spring deleted file mode 100644 index 405e1d60fc8f..000000000000 --- a/selenium/test/oauth/env.spring +++ /dev/null @@ -1,2 +0,0 @@ -export OAUTH_SERVER_CONFIG_DIR=${OAUTH_SERVER_CONFIG_BASEDIR}/oauth/spring -export OAUTH_SCOPES="openid profile rabbitmq.tag:management" diff --git a/selenium/test/oauth/env.spring-oauth-provider b/selenium/test/oauth/env.spring-oauth-provider deleted file mode 100644 index 979500cb8bd1..000000000000 --- a/selenium/test/oauth/env.spring-oauth-provider +++ /dev/null @@ -1,2 +0,0 @@ -export OAUTH_PROVIDER_URL=${SPRING_URL} -export OAUTH_PROVIDER_CA_CERT=${SPRING_CA_CERT} diff --git a/selenium/test/oauth/spring/application.yml b/selenium/test/oauth/spring/application.yml deleted file mode 100644 index 2ba5ad61a80c..000000000000 --- a/selenium/test/oauth/spring/application.yml +++ /dev/null @@ -1,64 +0,0 @@ -server: - port: 8443 - ssl: - bundle: spring-authorizationserver - -spring: - ssl: - bundle: - jks: - spring-authorizationserver: - key: - alias: server-spring-tls - password: foobar - keystore: - location: /config/server_spring.jks - password: foobar - type: PKCS12 - security: - oauth2: - users: - - username: rabbit_admin - password: rabbit_admin - scopes: - - openid - - profile - - rabbitmq.tag:administrator - audiencies: - - rabbitmq - authorizationserver: - client: - mgt_api_client: - registration: - provider: spring - client-id: mgt_api_client - authorization-grant-types: - - client_credentials - client-authentication-methods: - - client_secret_basic - token-settings: - access-token-format: reference - scopes: - - openid - - profile - - rabbitmq.tag:management - client-name: mgt_api_client - rabbitmq_client_code: - registration: - provider: spring - client-id: rabbitmq_client_code - require-proof-key: true - authorization-grant-types: - - authorization_code - client-authentication-methods: - - none - redirect-uris: - - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/js/oidc-oauth/login-callback.html" - post-logout-redirect-uris: - - "${RABBITMQ_SCHEME}://${RABBITMQ_HOST}${RABBITMQ_PATH}/" - scopes: - - openid - - profile - - rabbitmq.tag:administrator - - rabbitmq.tag:management - client-name: rabbitmq_client_code diff --git a/selenium/test/oauth/spring/openssl.cnf.in b/selenium/test/oauth/spring/openssl.cnf.in deleted file mode 100644 index 5ac3282046c5..000000000000 --- a/selenium/test/oauth/spring/openssl.cnf.in +++ /dev/null @@ -1,3 +0,0 @@ -[ client_alt_names ] -email.1 = rabbit_client@localhost -URI.1 = rabbit_client_id_uri From 054ad5eeb69f773060247a5cbde73768b7660ebc Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 18 Jun 2025 10:17:08 +0200 Subject: [PATCH 33/43] Bump up to 0.0.7 --- .github/workflows/authorization-server-make.yaml | 2 +- selenium/authorization-server/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index eca18ea38a80..77caff1088a8 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.6 + IMAGE_TAG: 0.0.7 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index d31091878a8a..47069d653dc0 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.6 + 0.0.7 authorization-server Authorization Server for Selenium From a53dfbf785a93038e56a5dd3eea0a3aa81bacaff Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 18 Jun 2025 10:28:20 +0200 Subject: [PATCH 34/43] Revert changes --- selenium/test/authnz-msg-protocols/mqtt.js | 1 + selenium/test/oauth/rabbitmq.conf | 2 -- selenium/test/oauth/rabbitmq.spring-oauth-provider.conf | 3 --- selenium/test/utils.js | 7 ++----- 4 files changed, 3 insertions(+), 10 deletions(-) delete mode 100644 selenium/test/oauth/rabbitmq.spring-oauth-provider.conf diff --git a/selenium/test/authnz-msg-protocols/mqtt.js b/selenium/test/authnz-msg-protocols/mqtt.js index d0a97825cd79..c6466a919d5a 100644 --- a/selenium/test/authnz-msg-protocols/mqtt.js +++ b/selenium/test/authnz-msg-protocols/mqtt.js @@ -45,6 +45,7 @@ describe('Having MQTT protocol enbled and the following auth_backends: ' + backe let oauthClientId = process.env.OAUTH_CLIENT_ID let oauthClientSecret = process.env.OAUTH_CLIENT_SECRET let openIdConfig = openIdConfiguration(oauthProviderUrl) + log("Obtained token_endpoint : " + openIdConfig.token_endpoint) password = tokenFor(oauthClientId, oauthClientSecret, openIdConfig.token_endpoint) log("Obtained access token : " + password) } diff --git a/selenium/test/oauth/rabbitmq.conf b/selenium/test/oauth/rabbitmq.conf index 2d96ff93e534..f101bae111c0 100644 --- a/selenium/test/oauth/rabbitmq.conf +++ b/selenium/test/oauth/rabbitmq.conf @@ -1,7 +1,5 @@ auth_backends.1 = rabbit_auth_backend_oauth2 -log.console.level = debug - management.login_session_timeout = 1 management.oauth_enabled = true management.oauth_client_id = rabbitmq_client_code diff --git a/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf b/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf deleted file mode 100644 index f4a8b882de38..000000000000 --- a/selenium/test/oauth/rabbitmq.spring-oauth-provider.conf +++ /dev/null @@ -1,3 +0,0 @@ -auth_oauth2.issuer = ${SPRING_URL} -auth_oauth2.https.cacertfile = ${SPRING_CA_CERT} -auth_oauth2.additional_scopes_key = extra_scope diff --git a/selenium/test/utils.js b/selenium/test/utils.js index 7662699cf70c..125a0c624b8f 100644 --- a/selenium/test/utils.js +++ b/selenium/test/utils.js @@ -236,15 +236,12 @@ module.exports = { } }, - tokenFor: (client_id, client_secret, url = uaaUrl, scopes = "") => { + tokenFor: (client_id, client_secret, url = uaaUrl) => { const req = new XMLHttpRequest() - let params = 'client_id=' + client_id + + const params = 'client_id=' + client_id + '&client_secret=' + client_secret + '&grant_type=client_credentials' + '&response_type=token' - if (scopes != "") { - params = params + "&scope=" + scopes - } req.open('POST', url, false) req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') req.setRequestHeader('Accept', 'application/json') From b228ca7501280ee84193986abadb92de38f612a1 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 18 Jun 2025 10:30:25 +0200 Subject: [PATCH 35/43] Revert changes --- ...tmq.auth_backends-oauth.conf => rabbitmq.backends-oauth.conf} | 0 selenium/test/utils.js | 1 + 2 files changed, 1 insertion(+) rename selenium/test/authnz-msg-protocols/{rabbitmq.auth_backends-oauth.conf => rabbitmq.backends-oauth.conf} (100%) diff --git a/selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth.conf b/selenium/test/authnz-msg-protocols/rabbitmq.backends-oauth.conf similarity index 100% rename from selenium/test/authnz-msg-protocols/rabbitmq.auth_backends-oauth.conf rename to selenium/test/authnz-msg-protocols/rabbitmq.backends-oauth.conf diff --git a/selenium/test/utils.js b/selenium/test/utils.js index 125a0c624b8f..c3b5379d56aa 100644 --- a/selenium/test/utils.js +++ b/selenium/test/utils.js @@ -241,6 +241,7 @@ module.exports = { const params = 'client_id=' + client_id + '&client_secret=' + client_secret + '&grant_type=client_credentials' + + '&token_format=jwt' + '&response_type=token' req.open('POST', url, false) req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') From 09a07cb81edd23e597d7b9a18265f41bb3e14b2f Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 1 Aug 2025 14:57:30 +0200 Subject: [PATCH 36/43] Add extra logging --- .../rabbitmq/authorization_server/AudienceAuthority.java | 5 +++++ .../rabbitmq/authorization_server/ScopeAuthority.java | 9 ++++++--- .../src/main/resources/application.yml | 3 +++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java index e81cb774e089..3d497e40bddf 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/AudienceAuthority.java @@ -23,6 +23,11 @@ public String getAuthority() { return authority; } + @Override + public String toString() { + return "Audience:" + authority; + } + public static List getAll(AbstractAuthenticationToken principal) { return principal.getAuthorities() .stream().filter(a -> a instanceof AudienceAuthority) diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java index 0dc88edd322a..3688ce773b6e 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/ScopeAuthority.java @@ -23,12 +23,15 @@ public String getAuthority() { return authority; } - public static List getAllUnauthorized(AbstractAuthenticationToken principal, - Set authorized) { + @Override + public String toString() { + return "Scope:" + authority; + } + + public static List getAuthorites(AbstractAuthenticationToken principal) { return principal.getAuthorities() .stream() .filter(a -> a instanceof ScopeAuthority) - .filter(a -> !authorized.contains(a.getAuthority())) .map(a -> a.getAuthority()).toList(); } diff --git a/selenium/authorization-server/src/main/resources/application.yml b/selenium/authorization-server/src/main/resources/application.yml index d45b72d3038c..a22f1c2ae998 100644 --- a/selenium/authorization-server/src/main/resources/application.yml +++ b/selenium/authorization-server/src/main/resources/application.yml @@ -1,3 +1,6 @@ +logging.level: + com.rabbitmq.authorization_server: DEBUG + server: port: 8443 ssl: From 2a6003c85e4fdeef89b8d79e2311ef70b5fde2d1 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 1 Aug 2025 14:57:36 +0200 Subject: [PATCH 37/43] =?UTF-8?q?Return=20all=20scopes=20without=20filteri?= =?UTF-8?q?ng=C2=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../authorization_server/SecurityConfig.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 22dc8bf4349b..26c6b642f5cd 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -5,6 +5,8 @@ import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,7 +38,7 @@ @Configuration @EnableWebSecurity public class SecurityConfig { - + @Bean @Order(1) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) @@ -112,21 +114,24 @@ private static KeyPair generateRsaKey() { return keyPair; } + Logger logger = LoggerFactory.getLogger(SecurityConfig.class); + @Bean public OAuth2TokenCustomizer jwtTokenCustomizer() { + logger.info("Creating jwtTokenCustomizer ..."); return (context) -> { if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { AbstractAuthenticationToken principal = context.getPrincipal(); - System.out.println("registered client: " + context.getRegisteredClient()); - System.out.println("token format : " + + logger.info("registered client: {}", context.getRegisteredClient()); + logger.info("principal : {}", principal); + logger.info("token format : {} ", context.getRegisteredClient().getTokenSettings().getAccessTokenFormat().getValue()); - System.out.println("authorities : " + principal.getAuthorities()); - System.out.println("authorized scopes : " + context.getAuthorizedScopes()); + logger.info("authorities : {}", principal.getAuthorities()); + logger.info("authorized scopes : {}", context.getAuthorizedScopes()); context.getClaims() .audience(AudienceAuthority.getAll(principal)) - .claim("extra_scope", ScopeAuthority.getAllUnauthorized(principal, - context.getAuthorizedScopes())); + .claim("extra_scope", ScopeAuthority.getAuthorites(principal)); } }; } From 2e669aeaed4f3438db1108d347e796d494f447cc Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 1 Aug 2025 17:20:40 +0200 Subject: [PATCH 38/43] Log token type when customizing token --- .../java/com/rabbitmq/authorization_server/SecurityConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 26c6b642f5cd..30c567ad7416 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -120,6 +120,7 @@ private static KeyPair generateRsaKey() { public OAuth2TokenCustomizer jwtTokenCustomizer() { logger.info("Creating jwtTokenCustomizer ..."); return (context) -> { + logger.info("Calling jwtTokenCustomizer with tokenType: {}", context.getTokenType()); if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { AbstractAuthenticationToken principal = context.getPrincipal(); logger.info("registered client: {}", context.getRegisteredClient()); From 4654d6cc9719241589f6028f18a0d6b2a884a454 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 1 Aug 2025 17:21:38 +0200 Subject: [PATCH 39/43] Bump up version --- selenium/authorization-server/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index 47069d653dc0..ff3400e979ae 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.7 + 0.0.8 authorization-server Authorization Server for Selenium From 82a6b1fa5fb8b6d22ffafde0cecad3a0cb1df143 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 1 Aug 2025 17:33:41 +0200 Subject: [PATCH 40/43] Bump up version --- .github/workflows/authorization-server-make.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index 77caff1088a8..768e48a2c989 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.7 + IMAGE_TAG: 0.0.8 jobs: docker: runs-on: ubuntu-latest From 5482cbb71ca893caf4953dc16ca9900119f8cd49 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 1 Aug 2025 18:15:13 +0200 Subject: [PATCH 41/43] Customize opaque access token with user's claims --- .../authorization_server/SecurityConfig.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 30c567ad7416..30068bfff6c4 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -28,6 +28,7 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; @@ -116,11 +117,29 @@ private static KeyPair generateRsaKey() { Logger logger = LoggerFactory.getLogger(SecurityConfig.class); + @Bean + public OAuth2TokenCustomizer accessTokenCustomizer() { + logger.info("Creating accessTokenCustomizer ..."); + return (context) -> { + logger.info("Calling accessTokenCustomizer with tokenType: {}", context.getTokenType().getValue()); + AbstractAuthenticationToken principal = context.getPrincipal(); + logger.info("registered client: {}", context.getRegisteredClient()); + logger.info("principal : {}", principal); + logger.info("token format : {} ", + context.getRegisteredClient().getTokenSettings().getAccessTokenFormat().getValue()); + logger.info("authorities : {}", principal.getAuthorities()); + logger.info("authorized scopes : {}", context.getAuthorizedScopes()); + + context.getClaims() + .audience(AudienceAuthority.getAll(principal)) + .claim("extra_scope", ScopeAuthority.getAuthorites(principal)); + }; + } @Bean public OAuth2TokenCustomizer jwtTokenCustomizer() { logger.info("Creating jwtTokenCustomizer ..."); return (context) -> { - logger.info("Calling jwtTokenCustomizer with tokenType: {}", context.getTokenType()); + logger.info("Calling jwtTokenCustomizer with tokenType: {}", context.getTokenType().getValue()); if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) { AbstractAuthenticationToken principal = context.getPrincipal(); logger.info("registered client: {}", context.getRegisteredClient()); From 4301251cbce7599e506d578634b1fde72226155a Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Fri, 1 Aug 2025 18:16:11 +0200 Subject: [PATCH 42/43] Bump up to 0.0.9 --- .github/workflows/authorization-server-make.yaml | 2 +- selenium/authorization-server/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index 768e48a2c989..d58e45d808dc 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.8 + IMAGE_TAG: 0.0.9 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index ff3400e979ae..39534afeb6d3 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.8 + 0.0.9 authorization-server Authorization Server for Selenium From 3dadfdfe9fd9715345e65bbec4ffb5da2d8dcb6f Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Mon, 4 Aug 2025 17:24:58 +0200 Subject: [PATCH 43/43] Generate introspected token with scopes from client when using client_credentials --- .../workflows/authorization-server-make.yaml | 2 +- selenium/authorization-server/pom.xml | 2 +- .../authorization_server/SecurityConfig.java | 22 ++++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/authorization-server-make.yaml b/.github/workflows/authorization-server-make.yaml index d58e45d808dc..f0e3427daabe 100644 --- a/.github/workflows/authorization-server-make.yaml +++ b/.github/workflows/authorization-server-make.yaml @@ -14,7 +14,7 @@ on: env: REGISTRY_IMAGE: pivotalrabbitmq/spring-authorization-server - IMAGE_TAG: 0.0.9 + IMAGE_TAG: 0.0.10 jobs: docker: runs-on: ubuntu-latest diff --git a/selenium/authorization-server/pom.xml b/selenium/authorization-server/pom.xml index 39534afeb6d3..f23f65e8ba9f 100644 --- a/selenium/authorization-server/pom.xml +++ b/selenium/authorization-server/pom.xml @@ -10,7 +10,7 @@ com.rabbitmq authorization-server - 0.0.9 + 0.0.10 authorization-server Authorization Server for Selenium diff --git a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java index 30068bfff6c4..e695a5bd2ad2 100644 --- a/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java +++ b/selenium/authorization-server/src/main/java/com/rabbitmq/authorization_server/SecurityConfig.java @@ -5,6 +5,9 @@ import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.UUID; +import java.util.Collection; +import java.util.List; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,6 +33,8 @@ import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext; +import org.springframework.security.oauth2.core.AuthorizationGrantType; + import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.ImmutableJWKSet; @@ -130,9 +135,20 @@ public OAuth2TokenCustomizer accessTokenCustomizer() logger.info("authorities : {}", principal.getAuthorities()); logger.info("authorized scopes : {}", context.getAuthorizedScopes()); - context.getClaims() - .audience(AudienceAuthority.getAll(principal)) - .claim("extra_scope", ScopeAuthority.getAuthorites(principal)); + if (AuthorizationGrantType.CLIENT_CREDENTIALS.equals(context.getAuthorizationGrantType())) { + Collection extra_scope = context.getRegisteredClient().getScopes(); + logger.info("granting extra_scope: {}", extra_scope); + context.getClaims() + .claim("extra_scope", extra_scope); + } else { + Collection extra_scope = ScopeAuthority.getAuthorites(principal); + List audience = AudienceAuthority.getAll(principal); + logger.info("granting extra_scope: {}", extra_scope); + logger.info("granting audience: {}", audience); + context.getClaims() + .audience(audience) + .claim("extra_scope", extra_scope); + } }; } @Bean