├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── Makefile ├── README.md ├── amqp1_0-client ├── .gitignore ├── Dockerfile ├── mvnw ├── mvnw.cmd ├── pom.xml ├── run └── src │ └── main │ ├── java │ └── com │ │ └── vmware │ │ └── rabbitmq │ │ └── App.java │ └── resources │ └── jndi.properties ├── assets └── select-oauth2-resource.png ├── bin ├── common ├── copy_scopes.py ├── curl_with_token ├── decode ├── deploy-rabbit ├── devkeycloak │ ├── curl │ ├── deploy │ └── token ├── jwt_token ├── jwt_token.py ├── keycloak │ ├── curl │ ├── deploy │ └── token ├── oauth2-proxy │ ├── deploy │ └── undeploy ├── open_url ├── portal │ └── deploy ├── prodkeycloak │ ├── curl │ ├── deploy │ └── token ├── proxy │ └── deploy ├── run-amqp1_0-client ├── run-demo-oauth-cf ├── run-jms-client ├── run-perftest └── uaa │ ├── curl_url │ ├── deploy │ └── token ├── conf ├── auth0 │ ├── rabbitmq.conf.tmpl │ ├── requires-tls │ └── tls.conf ├── enabled_plugins ├── entra │ ├── rabbitmq.conf.tmpl │ ├── requires-tls │ └── tls.conf ├── google │ ├── advanced.config │ └── rabbitmq.conf ├── keycloak │ ├── import │ │ ├── dev-realm.json │ │ ├── prod-realm.json │ │ └── test-realm.json │ ├── rabbitmq.conf │ └── signing-key │ │ └── signing-key.pem ├── multi-keycloak │ ├── dev_import │ │ └── dev-realm.json │ ├── prod_import │ │ └── prod-realm.json │ ├── rabbitmq.scenario1.basic.conf │ ├── rabbitmq.scenario1.conf │ ├── rabbitmq.scenario2.conf │ ├── rabbitmq.scenario3.conf │ └── signing-key │ │ └── signing-key.pem ├── oauth2-proxy │ ├── alpha-config.yaml │ ├── compose.yml │ ├── rabbitmq.conf │ └── signing-key │ │ └── signing-key.pem ├── okta │ ├── advanced.config │ ├── rabbitmq.conf.tmpl │ ├── requires-tls │ └── tls.conf ├── portal │ ├── Dockerfile │ ├── app.js │ ├── package.json │ ├── proxy.js │ ├── rabbitmq.conf │ ├── requires-tls │ ├── tls.conf │ └── views │ │ ├── rabbitmq.html │ │ └── unauthenticated.html ├── private-2.pem ├── private.pem ├── public-2.pem ├── public.pem ├── uaa-symmetrical │ ├── advanced.config │ ├── log4j2.properties │ ├── rabbitmq.conf │ └── uaa.yml └── uaa │ ├── advanced-scope-aliases.config │ ├── authn-and-authz.conf │ ├── log4j2.properties │ ├── oauth2-and-internal.conf │ ├── oauth2-only.conf │ ├── rabbitmq.conf │ ├── rar-tokens.conf │ ├── server.xml │ ├── signing-key │ └── signing-key.pem │ └── uaa.yml ├── jms-client ├── Dockerfile ├── pom.xml ├── run └── src │ └── main │ └── java │ └── com │ └── vmware │ └── rabbitmq │ └── App.java ├── jwts ├── consumer-roles-in-extra-scope.json ├── consumer-roles-scope.json ├── mgt-api-client.json ├── producer-role-in-extra-scope.json ├── producer-roles-in-extra-scope.json ├── producer-roles-in-scope.json ├── producer-without-scopes.json ├── rar-token.json ├── scope-and-extra-scope.json ├── scope-and-roles-in-extra-scope.json └── scopes-for-mqtt.json ├── oauth-resource-app ├── Dockerfile ├── Makefile ├── public │ ├── common.js │ ├── favicon.ico │ ├── index.html │ ├── login-callback.html │ ├── login.html │ └── logout-callback.html └── src │ ├── app.js │ └── server.js ├── pika-client └── producer.py └── stream_dot_net └── Keycloak ├── .gitignore ├── Keycloak.csproj ├── Program.cs └── README.md /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '42 22 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'java', 'python' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v2 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v2 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | conf/*/certs 2 | tls-gen 3 | *.tar.gz 4 | *.zip.* 5 | .idea 6 | .mvn 7 | *.iml 8 | conf/certs/* 9 | tls-gen/* 10 | .DS_Store 11 | conf/entra/rabbitmq.conf 12 | conf/auth0/rabbitmq.conf 13 | .DS_Store 14 | venv 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .ONESHELL:# single shell invocation for all lines in the recipe 2 | SHELL = bash# we depend on bash expansion for e.g. queue patterns 3 | 4 | .DEFAULT_GOAL = help 5 | PRODUCER := producer 6 | CONSUMER := consumer 7 | 8 | 9 | ### TARGETS ### 10 | 11 | help: 12 | @grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 13 | 14 | install-uaac: ## Install UAA Client 15 | @echo "Installing uaac client on your local machine " 16 | @(gem list --local | grep cf-uaac || sudo gem install cf-uaac && echo "Already installed") 17 | 18 | start-uaa: ## Start uaa (remember to run make build-uaa if you have not done ) 19 | @./bin/uaa/deploy 20 | 21 | start-keycloak: ## Start keycloak 22 | @./bin/keycloak/deploy 23 | 24 | start-forward-proxy: ## Start forward-proxy 25 | @./bin/forward-proxy/deploy 26 | 27 | start-portal: ## Start portal 28 | @./bin/portal/deploy 29 | 30 | start-proxy: ## Start proxy 31 | @./bin/proxy/deploy 32 | 33 | stop-uaa: ## Stop uaa 34 | @docker kill uaa 35 | 36 | stop-keycloak: ## Stop keycloak 37 | @docker kill keycloak 38 | 39 | stop-forward-proxy: ## Stop forward-proxy 40 | @docker kill forward-proxy 41 | 42 | stop-portal: ## Stop portal 43 | @docker kill portal 44 | 45 | stop-proxy: ## Stop proxy 46 | @docker kill proxy 47 | 48 | stop-dev-keycloak: ## Stop dev keycloak 49 | @docker kill devkeycloak 50 | @docker rm devkeycloak 51 | 52 | stop-prod-keycloak: ## Stop dev keycloak 53 | @docker kill prodkeycloak 54 | @docker rm prodkeycloak 55 | 56 | start-oauth2-proxy: ## Start oauth2-proxy 57 | @bin/oauth2-proxy/deploy 58 | 59 | stop-oauth2-proxy: ## Stop oauth2-proxy 60 | @bin/oauth2-proxy/undeploy 61 | 62 | start-rabbitmq: ## Run RabbitMQ Server 63 | @./bin/deploy-rabbit 64 | 65 | stop-rabbitmq: 66 | @docker stop rabbitmq 67 | 68 | start-perftest-producer: ## Start PerfTest producer application 69 | @uaac token client get $(PRODUCER) -s $(PRODUCER)_secret 70 | @./bin/run-perftest $(PRODUCER) \ 71 | --queue "q-perf-test" \ 72 | --producers 1 \ 73 | --consumers 0 \ 74 | --rate 1 \ 75 | --flag persistent \ 76 | --exchange "x-incoming-transaction" \ 77 | --auto-delete "false" 78 | 79 | start-perftest-producer-with-token: ## Start PerfTest producer application with a token 80 | @TOKEN=$(TOKEN) ./bin/run-perftest $(PRODUCER)\ 81 | --queue "q-perf-test" \ 82 | --producers 1 \ 83 | --consumers 0 \ 84 | --rate 1 \ 85 | --flag persistent \ 86 | --exchange "x-incoming-transaction" \ 87 | --auto-delete "false" 88 | 89 | stop-perftest-producer: ## Stop perfTest producer 90 | @docker stop $(PRODUCER) 91 | 92 | start-perftest-consumer: ## Start Perftest consumer application 93 | @uaac token client get $(CONSUMER) -s $(CONSUMER)_secret 94 | @./bin/run-perftest $(CONSUMER) \ 95 | --queue "q-perf-test" \ 96 | --producers 0 \ 97 | --consumers 1 \ 98 | --rate 1 \ 99 | --flag persistent \ 100 | --exchange "x-incoming-transaction" \ 101 | --auto-delete "false" 102 | 103 | start-perftest-consumer-with-token: ## Start Perftest consumer application with a token 104 | @TOKEN=$(TOKEN) ./bin/run-perftest $(CONSUMER) \ 105 | --queue "q-perf-test" \ 106 | --producers 0 \ 107 | --consumers 1 \ 108 | --rate 1 \ 109 | --flag persistent \ 110 | --exchange "x-incoming-transaction" \ 111 | --auto-delete "false" 112 | 113 | stop-perftest-consumer: ## Stop perfTest consumer 114 | @docker stop $(CONSUMER) 115 | 116 | 117 | stop-all-apps: ## Stop all appications we can start with this Makefile 118 | @docker kill consumer producer 2>/dev/null 119 | 120 | pivotalrabbitmq/perf-test:latest 121 | 122 | curl-uaa: ## Run curl with a JWT token. Syntax: make curl-uaa url=http://localhost:15672/api/overview client_id=rabbit_monitor secret=rabbit_monitor 123 | @uaac token client get $(client_id) -s $(secret) 124 | @./bin/uaa/curl_url $(client_id) $(url) 125 | 126 | curl-keycloak: ## Run curl with a JWT token. Syntax: make curl-keycloak url=http://localhost:15672/api/overview client_id=rabbit_monitor secret=rabbit_monitor realm=test 127 | @./bin/keycloak/curl $(url) $(client_id) $(secret) ${realm} 128 | 129 | curl-dev-keycloak: ## Run curl with a JWT token. Syntax: make curl-dev-keycloak url=http://localhost:15672/api/overview client_id=rabbit_monitor secret=rabbit_monitor 130 | @./bin/devkeycloak/curl $(url) $(client_id) $(secret) 131 | 132 | curl-prod-keycloak: ## Run curl with a JWT token. Syntax: make curl-prod-keycloak url=http://localhost:15672/api/overview client_id=rabbit_monitor secret=rabbit_monitor 133 | @./bin/prodkeycloak/curl $(url) $(client_id) $(secret) 134 | 135 | open: ## Open the browser and login the user with the JWT Token. e.g: make open username=rabbit_admin password=rabbit_admin 136 | @./bin/open_url $(username) $(password) 137 | 138 | build-jms-client: ## build jms client docker image 139 | @(docker build jms-client/. -t jms-client) 140 | 141 | start-jms-publisher: ## start jms publisher that sends 1 message 142 | @uaac token client get jms_producer -s jms_producer_secret 143 | @./bin/run-jms-client jms_producer pub 144 | 145 | start-jms-subscriber: ## start jms subscriber 146 | @uaac token client get jms_consumer -s jms_consumer_secret 147 | @./bin/run-jms-client jms_consumer sub 148 | 149 | build-amqp1_0-client: ## build amqp1_0 client docker image 150 | @(docker build amqp1_0-client/. -t amqp1_0-client) 151 | 152 | start-amqp1_0-publisher: ## start amqp publisher that sends 1 message 153 | @uaac token client get producer -s producer_secret 154 | @./bin/run-amqp1_0-client producer pub 155 | 156 | start-amqp1_0-subscriber: ## start amqp subscriber 157 | @uaac token client get consumer -s consumer_secret 158 | @./bin/run-amqp1_0-client consumer sub 159 | 160 | curl-with-token: ## Run curl with a JWT token. Syntax: make curl-with-extra-scopes URL=http://localhost:15672/api/overview TOKEN=.... 161 | @curl -u :$(TOKEN) $(URL) 162 | 163 | get-jwt-token: ## Get a JWT token from an authorzation server 164 | @curl curl --request POST \ 165 | --url 'https://' \ 166 | --header 'content-type: application/x-www-form-urlencoded' \ 167 | --data grant_type=client_credentials \ 168 | --data client_id= \ 169 | --data client_secret= \ 170 | --data audience="rabbitmq:15672" 171 | 172 | start-mqtt-publish: ## publish mqtt message . e.g. make start-mqtt-publish TOKEN=$(bin/jwt_token legacy-token-key private.pem public.pem) 173 | @(docker run --rm -it --network rabbitmq_net ruimarinho/mosquitto mosquitto_pub \ 174 | -h rabbitmq -u "" -P $(TOKEN) -t test -m hello-world) 175 | 176 | clean-certs: ## remove all auto-generated certificates from any oauth provider and rabbitmq 177 | @rm -r conf/*/certs -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RabbitMQ OAuth2 Tutorial 2 | 3 | The instructions on how to configure and test OAuth 2.0 in RabbitMQ have been moved to [RabbitMQ documentation](https://www.rabbitmq.com/docs/oauth2-examples). This repository only maintains the configuration files and scripts referenced from the RabbitMQ documentation. 4 | 5 | **IMPORTANT** 6 | This branch, `main`, of this repository is meant for the RabbitMQ docs with the version `4.0` or earlier. 7 | For RabbitMQ docs with version `Next`, check the branch [next](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/next). 8 | 9 | 10 | **Table of Contents** 11 | 12 | * [Layout](#layout) 13 | * [Examples](#examples) 14 | 15 | ## Layout 16 | 17 | For each OAuth provider, there is a subfolder under `conf` folder, such as `keycloak`, 18 | or `entra`. If the OAuth provider can be deployed locally via docker, there is also a subfolder under `bin` folder, such as `bin/keycloak`, with a `deploy` script. 19 | 20 | ### RabbitMQ Configuration file 21 | 22 | Under each OAuth provider folder, you find either a `rabbitmq.conf` file for those OAuth providers that can be deployed locally, such as `keycloak` and `uaa`. For SaaS OAuth providers like `entra`, you find instead a `rabbitmq.conf.tmpl` file that you need to clone as `rabbitmq.conf` and replace template variables such as `{Application(client) ID}` with a real value. 23 | 24 | ### RabbitMQ TLS enabled 25 | 26 | When the example requires RabbitMQ with TLS enabled, the corresponding `conf` folder must have a file called `requires-tls`. When you run `make start-rabbitmq`, if the key and cert have not been generated yet, the command generates one. For instance, under `conf/entra` there is a `requires-tls` file. When you deploy RabbitMQ with `MODE=entra`, a key-pair is generated under `conf/entra/certs`. In `conf/entra/rabbitmq.conf.tmpl` configuration file you can see where the certificates and key are mounted. 27 | 28 | ## Examples 29 | 30 | ### Management UI Access 31 | 32 | * [Access management UI using OAuth 2.0 tokens](https://www.rabbitmq.com/docs/oauth2-examples#access-management-ui) 33 | * [Service-Provider initiated logon](https://www.rabbitmq.com/docs/oauth2-examples#service-provider-initiated-logon) 34 | * [Identity-Provider initiated logon](https://www.rabbitmq.com/docs/oauth2-examples#identity-provider-initiated-logon) 35 | 36 | ### Using [JWT tokens in several protocols](#access-other-protocols) to access RabbitMQ 37 | 38 | * [Management HTTP API](https://www.rabbitmq.com/docs/oauth2-examples#management-http-api) 39 | * [AMQP 0-9-1](https://www.rabbitmq.com/docs/oauth2-examples#amqp-protocol) (and [scopes for topic exchanges](https://www.rabbitmq.com/docs/oauth2-examples#using-topic-exchanges) in a separate section) 40 | * [AMQP 1.0](https://www.rabbitmq.com/docs/oauth2-examples#amqp10-protocol) 41 | * [JMS](https://www.rabbitmq.com/docs/oauth2-examples#jms-clients) 42 | * [MQTT](https://www.rabbitmq.com/docs/oauth2-examples#mqtt-protocol) 43 | 44 | ### Signing Keys, Scope Aliases, Rich Authorization Requests 45 | 46 | * [How to Use Advanced OAuth 2.0 Configuration](https://www.rabbitmq.com/docs/oauth2-examples#advanced-configuration) 47 | * [Using a custom scope field](https://www.rabbitmq.com/docs/oauth2-examples#using-custom-scope-field) 48 | * [Using multiple asymmetrical signing keys](https://www.rabbitmq.com/docs/oauth2-examples#using-multiple-asymmetrical-signing-keys) 49 | * [Using scope aliases](https://www.rabbitmq.com/docs/oauth2-examples#using-scope-aliases) 50 | * [Preferred username claims](https://www.rabbitmq.com/docs/oauth2-examples#preferred-username-claims) 51 | * [Using Rich Authorization Requests tokens](https://www.rabbitmq.com/docs/oauth2-examples#use-rar-tokens) 52 | 53 | ### Examples for Specific OAuth 2.0 Identity Providers 54 | 55 | * [Keycloak](https://www.rabbitmq.com/docs/oauth2-examples-keycloak) 56 | * [Auth0](https://www.rabbitmq.com/docs/oauth2-examples-auth0) 57 | * [Microsoft Entra ID](https://www.rabbitmq.com/docs/oauth2-examples-entra-id) (formerly known as Azure Active Directory) 58 | * [OAuth2 Proxy](https://www.rabbitmq.com/docs/oauth2-examples-proxy) 59 | * [Okta](https://www.rabbitmq.com/docs/oauth2-examples-okta) 60 | * [Google](https://www.rabbitmq.com/docs/oauth2-examples-google) **NOT SUPPORTED** 61 | * [Multiple OAuth 2.0 servers and/or audiences](https://www.rabbitmq.com/docs/oauth2-examples-multiresource) 62 | * [Identity Provider initiated logon with a web portal](https://www.rabbitmq.com/docs/oauth2-examples-idp-initiated) 63 | 64 | ### Commercial-only features 65 | 66 | * [Explicit forward proxy](https://techdocs.broadcom.com/us/en/vmware-tanzu/data-solutions/tanzu-rabbitmq-oci/4-0/tanzu-rabbitmq-oci-image/overview.html) 67 | -------------------------------------------------------------------------------- /amqp1_0-client/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /amqp1_0-client/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################ 2 | # STEP 1 build executable binary 3 | ############################ 4 | 5 | FROM maven:3.8.4-jdk-11 as builder 6 | 7 | WORKDIR /workspace 8 | 9 | COPY src ./src 10 | COPY pom.xml ./ 11 | 12 | RUN mvn 13 | 14 | 15 | ############################ 16 | # STEP 2 build a small image 17 | ############################ 18 | FROM openjdk:11 19 | WORKDIR / 20 | # Copy our static executable. 21 | COPY --from=builder /workspace/target . 22 | ENTRYPOINT ["java", "-jar", "amqp1_0-client-1.0-SNAPSHOT-jar-with-dependencies.jar"] 23 | -------------------------------------------------------------------------------- /amqp1_0-client/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | ########################################################################################## 204 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 205 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 206 | ########################################################################################## 207 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 208 | if [ "$MVNW_VERBOSE" = true ]; then 209 | echo "Found .mvn/wrapper/maven-wrapper.jar" 210 | fi 211 | else 212 | if [ "$MVNW_VERBOSE" = true ]; then 213 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 214 | fi 215 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 216 | while IFS="=" read key value; do 217 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 218 | esac 219 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 220 | if [ "$MVNW_VERBOSE" = true ]; then 221 | echo "Downloading from: $jarUrl" 222 | fi 223 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 224 | 225 | if command -v wget > /dev/null; then 226 | if [ "$MVNW_VERBOSE" = true ]; then 227 | echo "Found wget ... using wget" 228 | fi 229 | wget "$jarUrl" -O "$wrapperJarPath" 230 | elif command -v curl > /dev/null; then 231 | if [ "$MVNW_VERBOSE" = true ]; then 232 | echo "Found curl ... using curl" 233 | fi 234 | curl -o "$wrapperJarPath" "$jarUrl" 235 | else 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Falling back to using Java to download" 238 | fi 239 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 240 | if [ -e "$javaClass" ]; then 241 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 242 | if [ "$MVNW_VERBOSE" = true ]; then 243 | echo " - Compiling MavenWrapperDownloader.java ..." 244 | fi 245 | # Compiling the Java class 246 | ("$JAVA_HOME/bin/javac" "$javaClass") 247 | fi 248 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 249 | # Running the downloader 250 | if [ "$MVNW_VERBOSE" = true ]; then 251 | echo " - Running MavenWrapperDownloader.java ..." 252 | fi 253 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 254 | fi 255 | fi 256 | fi 257 | fi 258 | ########################################################################################## 259 | # End of extension 260 | ########################################################################################## 261 | 262 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 263 | if [ "$MVNW_VERBOSE" = true ]; then 264 | echo $MAVEN_PROJECTBASEDIR 265 | fi 266 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 267 | 268 | # For Cygwin, switch paths to Windows format before running java 269 | if $cygwin; then 270 | [ -n "$M2_HOME" ] && 271 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 272 | [ -n "$JAVA_HOME" ] && 273 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 274 | [ -n "$CLASSPATH" ] && 275 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 276 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 277 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 278 | fi 279 | 280 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 281 | 282 | exec "$JAVACMD" \ 283 | $MAVEN_OPTS \ 284 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 285 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 286 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 287 | -------------------------------------------------------------------------------- /amqp1_0-client/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /amqp1_0-client/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.vmware.rabbitmq 5 | amqp1_0-client 6 | jar 7 | 1.0-SNAPSHOT 8 | amqp1_0-client 9 | https://www.rabbitmq.com 10 | 11 | 12 | org.apache.qpid 13 | qpid-jms-client 14 | 2.2.0 15 | 16 | 17 | 18 | 1.8 19 | 3.8.1 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | install 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-compiler-plugin 30 | ${maven.compiler.version} 31 | 32 | ${java.version} 33 | ${java.version} 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-assembly-plugin 39 | 40 | 41 | package 42 | 43 | single 44 | 45 | 46 | 47 | 48 | 49 | com.vmware.rabbitmq.App 50 | 51 | 52 | 53 | 54 | jar-with-dependencies 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /amqp1_0-client/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CLIENT_ID=${1:?First parameter must be client id} 4 | 5 | token=$(uaac context $CLIENT_ID | awk '/access_token/ { print $2}') 6 | queue=${QUEUE:-q-test-queue} 7 | 8 | shift 1 9 | 10 | echo "Launching AMQP1.0-client with a token for Oauth Client $CLIENT_ID " 11 | echo "QUEUE: $queue" 12 | echo "TOKEN: $token" 13 | 14 | USERNAME=" " PASSWORD=$token QUEUE=$queue java -jar target/amqp1_0-client-1.0-SNAPSHOT-jar-with-dependencies.jar $@ 15 | -------------------------------------------------------------------------------- /amqp1_0-client/src/main/java/com/vmware/rabbitmq/App.java: -------------------------------------------------------------------------------- 1 | package com.vmware.rabbitmq; 2 | 3 | 4 | import jakarta.jms.*; 5 | 6 | import javax.naming.Context; 7 | import javax.naming.InitialContext; 8 | 9 | /** 10 | * Unit test for simple App. 11 | */ 12 | public class App { 13 | private static final int RABBIT_PORT = 5672; 14 | private static final int RABBIT_TLS_PORT = 5671; 15 | private final Command command; 16 | private boolean secure; 17 | private int qbrMax; 18 | private String username; 19 | private String password; 20 | private String message = "hello world"; 21 | 22 | enum Command { pub, sub } 23 | 24 | public App(Command command, String username, String password, boolean secure) { 25 | this.command = command; 26 | this.username = username; 27 | this.password = password; 28 | this.secure = secure; 29 | this.qbrMax = 0; 30 | } 31 | 32 | public static void main( String[] args ) { 33 | if (args.length < 1) { 34 | throw new RuntimeException("Missing 1st parameter [pub or sub]"); 35 | } 36 | new App(Command.valueOf(args[0]), username(), password(), isSecure()).run(); 37 | } 38 | 39 | private static String username() { 40 | return System.getenv("USERNAME"); 41 | } 42 | private static String password() { 43 | return System.getenv("PASSWORD"); 44 | } 45 | private static boolean isSecure() { 46 | String secureOption = System.getenv("SECURE"); 47 | return secureOption != null && Boolean.parseBoolean(secureOption); 48 | } 49 | public void run() { 50 | System.out.printf("Running command %s\n", command); 51 | 52 | switch(command) { 53 | case pub: 54 | sendMessage(); 55 | break; 56 | case sub: 57 | receivedMessage(); 58 | break; 59 | } 60 | } 61 | 62 | private void receivedMessage() { 63 | try { 64 | // The configuration for the Qpid InitialContextFactory has been supplied in 65 | // a jndi.properties file in the classpath, which results in it being picked 66 | // up automatically by the InitialContext constructor. 67 | Context context = new InitialContext(); 68 | 69 | ConnectionFactory factory = (ConnectionFactory) context.lookup("myFactoryLookup"); 70 | Destination queue = (Destination) context.lookup("myQueueLookup"); 71 | 72 | Connection connection = factory.createConnection(username, password); 73 | connection.setExceptionListener(new MyExceptionListener()); 74 | connection.start(); 75 | 76 | Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 77 | 78 | MessageConsumer messageConsumer = session.createConsumer(queue); 79 | 80 | int timeout = 1000; 81 | Message message = messageConsumer.receive(timeout); 82 | if (message == null) { 83 | System.out.println("Message not received within timeout, stopping."); 84 | return; 85 | } 86 | System.out.println("Received message"); 87 | 88 | connection.close(); 89 | } catch (Exception exp) { 90 | System.out.println("Caught exception, exiting."); 91 | exp.printStackTrace(System.out); 92 | System.exit(1); 93 | } 94 | } 95 | 96 | private void sendMessage() { 97 | try { 98 | // The configuration for the Qpid InitialContextFactory has been supplied in 99 | // a jndi.properties file in the classpath, which results in it being picked 100 | // up automatically by the InitialContext constructor. 101 | Context context = new InitialContext(); 102 | 103 | ConnectionFactory factory = (ConnectionFactory) context.lookup("myFactoryLookup"); 104 | Destination queue = (Destination) context.lookup("myQueueLookup"); 105 | 106 | Connection connection = factory.createConnection(username, password); 107 | connection.setExceptionListener(new MyExceptionListener()); 108 | connection.start(); 109 | 110 | Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 111 | 112 | MessageProducer messageProducer = session.createProducer(queue); 113 | 114 | TextMessage textMessage = session.createTextMessage(message); 115 | messageProducer.send(textMessage, DeliveryMode.NON_PERSISTENT, Message.DEFAULT_PRIORITY, 116 | Message.DEFAULT_TIME_TO_LIVE); 117 | 118 | connection.close(); 119 | } catch (Exception exp) { 120 | System.out.println("Caught exception, exiting."); 121 | exp.printStackTrace(System.out); 122 | System.exit(1); 123 | } 124 | } 125 | 126 | private static class MyExceptionListener implements ExceptionListener { 127 | 128 | public void onException(JMSException exception) { 129 | System.out.println("Connection ExceptionListener fired, exiting."); 130 | exception.printStackTrace(System.out); 131 | System.exit(1); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /amqp1_0-client/src/main/resources/jndi.properties: -------------------------------------------------------------------------------- 1 | 2 | # Set the InitialContextFactory class to use 3 | java.naming.factory.initial=org.apache.qpid.jms.jndi.JmsInitialContextFactory 4 | 5 | # Define the required ConnectionFactory instances 6 | # connectionfactory. = 7 | connectionfactory.myFactoryLookup=amqp://rabbitmq:5672 8 | 9 | # Configure the necessary Queue and Topic objects 10 | # queue. = 11 | # topic. = 12 | queue.myQueueLookup=q-test-queue 13 | topic.myTopicLookup=q-test-topic 14 | -------------------------------------------------------------------------------- /assets/select-oauth2-resource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitmq/rabbitmq-oauth2-tutorial/e1b959370ab7b626a0cb7635957be8ea623a3bac/assets/select-oauth2-resource.png -------------------------------------------------------------------------------- /bin/common: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | ROOT=$SCRIPT/.. 5 | 6 | tabs 1 7 | declare -i PADDING_LEVEL=0 8 | declare -i STEP=1 9 | 10 | begin() { 11 | print "\n[$STEP] $@" 12 | PADDING_LEVEL=$(($PADDING_LEVEL + 1)) 13 | STEP=$(($STEP + 1)) 14 | } 15 | end() { 16 | PADDING_LEVEL=$(($PADDING_LEVEL - 1)) 17 | print "$@" 18 | } 19 | print() { 20 | tabbing="" 21 | if [[ $PADDING_LEVEL -gt 0 ]]; then 22 | for i in $(seq $PADDING_LEVEL); do 23 | tabbing="$tabbing\t" 24 | done 25 | fi 26 | echo -e "$tabbing$1" 27 | } 28 | 29 | wait_for_message() { 30 | attemps_left=10 31 | while ! docker logs $1 2>&1 | grep -q "$2"; 32 | do 33 | sleep 5 34 | print "Waiting 5sec for $1 to start ($attemps_left attempts left )..." 35 | ((attemps_left--)) 36 | if [[ "$attemps_left" -lt 1 ]]; then 37 | print "Timed out waiting" 38 | exit 1 39 | fi 40 | done 41 | } 42 | kill_container_if_exist() { 43 | if docker stop $1 &> /dev/null; then 44 | docker rm $1 &> /dev/null 45 | fi 46 | } 47 | ensure_docker_network() { 48 | NETWORK=${DOCKER_NETWORK:-rabbitmq_net} 49 | begin "Ensuring $NETWORK network ..." 50 | if [ ! "$(docker network ls | grep $NETWORK)" ]; then 51 | print "> DOCKER_NETWORK: $NETWORK created" 52 | docker network create $NETWORK 53 | fi 54 | end "$NETWORK network exists" 55 | } 56 | 57 | function generate-ca-server-client-kpi { 58 | NAME=$1 59 | FOLDER=$2 60 | if [[ ! -f "${FOLDER}/server_${NAME}_key.pem" ]]; then 61 | do_generate-ca-server-client-kpi $1 $2 62 | fi 63 | } 64 | function do_generate-ca-server-client-kpi { 65 | NAME=$1 66 | FOLDER=$2 67 | begin "Generate certs for $NAME" 68 | 69 | if [ -d "$NAME" ]; then 70 | end "SSL Certificates already present under $NAME. Skip SSL generation" 71 | return 72 | fi 73 | 74 | if [ ! -d "$ROOT/tls-gen" ]; then 75 | git clone https://github.com/michaelklishin/tls-gen $ROOT/tls-gen 76 | fi 77 | 78 | print "Generating CA and Server (localhost and $NAME) PKI under $FOLDER ..." 79 | mkdir -p $FOLDER 80 | 81 | CUR_DIR=$(pwd) 82 | cd $ROOT/tls-gen/basic 83 | make CN=$NAME 84 | #make PASSWORD=foobar 85 | make verify 86 | make info 87 | cd $CUR_DIR 88 | 89 | cp $ROOT/tls-gen/basic/result/ca_certificate.pem $FOLDER/ca_${NAME}_certificate.pem 90 | cp $ROOT/tls-gen/basic/result/server_${NAME}_certificate.pem $FOLDER 91 | cp $ROOT/tls-gen/basic/result/server_${NAME}_key.pem $FOLDER 92 | cp $ROOT/tls-gen/basic/result/server_${NAME}.p12 $FOLDER 93 | chmod 777 $FOLDER/* 94 | end "SSL Certificates generated for $NAME under $FOLDER" 95 | } 96 | -------------------------------------------------------------------------------- /bin/copy_scopes.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python3 2 | 3 | import jwt 4 | import time 5 | import sys 6 | from datetime import datetime 7 | from datetime import timedelta 8 | 9 | private_key = open(sys.argv[1], "r").read() 10 | public_key = open(sys.argv[2], "r").read() 11 | audience = sys.argv[3] 12 | new_scope_attribute = sys.argv[4] 13 | encoded_jwt = sys.argv[5] 14 | 15 | decoded_jwt = jwt.decode(encoded_jwt, public_key, audience=audience, algorithms=["RS256"]) 16 | #print(decoded_jwt) 17 | 18 | headers = jwt.get_unverified_header(encoded_jwt) 19 | #print(headers) 20 | 21 | decoded_jwt[new_scope_attribute] = decoded_jwt['scope'] 22 | 23 | encoded = jwt.encode(decoded_jwt, private_key, algorithm="RS256") 24 | print(encoded) 25 | -------------------------------------------------------------------------------- /bin/curl_with_token: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | URL=${1:?First parameter must be the url to curl} 6 | TOKEN=${2:?Second parameter must be the token} 7 | 8 | curl -k -u :$TOKEN $URL 9 | -------------------------------------------------------------------------------- /bin/decode: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | jwtd() { 4 | if [[ -x $(command -v jq) ]]; then 5 | jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< "${1}" 6 | echo "Signature: $(echo "${1}" | awk -F'.' '{print $3}')" 7 | fi 8 | } 9 | 10 | jwtd $1 11 | -------------------------------------------------------------------------------- /bin/deploy-rabbit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ! -z "${DEBUG}" ]]; then 4 | set -x 5 | fi 6 | 7 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 8 | 9 | source $SCRIPT/common 10 | 11 | MODE=${MODE:-uaa} 12 | OAUTH_PROVIDER=${OAUTH_PROVIDER:-$MODE} 13 | ADVANCED=${ADVANCED:-advanced.config} 14 | IMAGE_TAG=${IMAGE_TAG:-4.0.8-management} 15 | IMAGE=${IMAGE:-rabbitmq} 16 | RABBITMQ_CONF=${RABBITMQ_CONF:-rabbitmq.conf} 17 | 18 | if [[ "${MODE}" == "uaa" ]]; then 19 | if [[ -z "${CONF_FILES}" ]]; then 20 | CONF_FILES="rabbitmq,oauth2-only" 21 | fi 22 | fi 23 | 24 | CONF_DIR=$SCRIPT/../conf/${MODE} 25 | CERTS_DIR=${CONF_DIR}/certs 26 | RABBIT_NETWORK=${RABBIT_NETWORK:-rabbitmq_net} 27 | 28 | function generate-final-conf-dir { 29 | FINAL_CONF_DIR=`mktemp -d -t "oauth2XXXXX"` 30 | 31 | if [[ -z "${CONF_FILES}" ]]; then 32 | for i in $CONF_DIR/*.conf 33 | do 34 | cp $i $FINAL_CONF_DIR 35 | done 36 | cp ${CONF_DIR}/${RABBITMQ_CONF} $FINAL_CONF_DIR 37 | else 38 | for i in ${CONF_FILES//,/ } 39 | do 40 | cp $CONF_DIR/${i}.conf $FINAL_CONF_DIR 41 | done 42 | fi 43 | 44 | } 45 | function generate-tls-certs-if-required { 46 | if [[ -f "${CONF_DIR}/requires-tls" && ! -f "${CERTS_DIR}/server_rabbitmq_certificate.pem" ]]; then 47 | generate-ca-server-client-kpi rabbitmq $CERTS_DIR 48 | fi 49 | } 50 | 51 | function deploy { 52 | cp ${SCRIPT}/../conf/enabled_plugins ${FINAL_CONF_DIR} 53 | chmod o+rwx ${FINAL_CONF_DIR} 54 | EXTRA_MOUNTS="${EXTRA_MOUNTS} -v ${FINAL_CONF_DIR}:/etc/rabbitmq -v ${CERTS_DIR}:/certs " 55 | USED_CONFIG="${FINAL_CONF_DIR}/*.conf " 56 | 57 | if [[ -f "${CONF_DIR}/requires-tls" ]]; then 58 | EXTRA_PORTS="-p 15671:15671 " 59 | fi 60 | EXTRA_MOUNTS="${EXTRA_MOUNTS} -v $SCRIPT/../conf/${OAUTH_PROVIDER}/certs:/etc/${OAUTH_PROVIDER}/certs " 61 | 62 | 63 | if [[ -n "${ADVANCED}" && -f "${CONF_DIR}/${ADVANCED}" ]]; then 64 | EXTRA_MOUNTS="${EXTRA_MOUNTS} -v ${CONF_DIR}/${ADVANCED}:/etc/rabbitmq/advanced.config:ro " 65 | USED_CONFIG="${USED_CONFIG} ${CONF_DIR}/${ADVANCED}" 66 | fi 67 | 68 | echo "Running RabbitMQ ($IMAGE:$IMAGE_TAG) with" 69 | echo " - Mode: ${MODE} " 70 | echo " - OauthProvider: ${OAUTH_PROVIDER}" 71 | echo " - configuration file(s): ${USED_CONFIG}" 72 | echo " - mounts: ${EXTRA_MOUNTS}" 73 | 74 | PLATFORM_ARGS="" 75 | if [[ -n "${PLATFORM}" ]]; then 76 | PLATFORM_ARGS="--platform ${PLATFORM} " 77 | fi 78 | 79 | docker run -d --name rabbitmq \ 80 | --net ${RABBIT_NETWORK} \ 81 | ${PLATFORM_ARGS} \ 82 | -p 15672:15672 \ 83 | -p 5672:5672 \ 84 | -p 5552:5552 \ 85 | ${EXTRA_PORTS} \ 86 | ${EXTRA_MOUNTS} \ 87 | ${IMAGE}:${IMAGE_TAG} 88 | } 89 | 90 | generate-final-conf-dir 91 | generate-tls-certs-if-required 92 | ensure_docker_network 93 | kill_container_if_exist rabbitmq 94 | deploy 95 | wait_for_message rabbitmq "completed with" 96 | print "RabbitMQ is running" 97 | -------------------------------------------------------------------------------- /bin/devkeycloak/curl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | URL=${1:?First parameter must be the url} 7 | CLIENT_ID=${2:?Second parameter must be client_id} 8 | CLIENT_SECRET=${3:?Third parameter must be the client_secret} 9 | 10 | ACCESS_TOKEN=$($SCRIPT/token ${CLIENT_ID} ${CLIENT_SECRET}) 11 | 12 | curl -k -u :$ACCESS_TOKEN $URL 13 | -------------------------------------------------------------------------------- /bin/devkeycloak/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | ROOT=$SCRIPT/../.. 5 | CONF_DIR=${ROOT}/conf/multi-keycloak 6 | CERTS_DIR=${CONF_DIR}/certs 7 | 8 | ensure_docker_network 9 | kill_container_if_exist devkeycloak 10 | 11 | generate-ca-server-client-kpi devkeycloak $CERTS_DIR 12 | 13 | echo "Running devkeycloack docker image ..." 14 | 15 | docker run \ 16 | --detach \ 17 | --name devkeycloak --net rabbitmq_net \ 18 | --publish 8081:8080 \ 19 | --publish 8443:8443 \ 20 | --env KEYCLOAK_ADMIN=admin \ 21 | --env KEYCLOAK_ADMIN_PASSWORD=admin \ 22 | --mount type=bind,source=${CONF_DIR}/dev_import/,target=/opt/keycloak/data/import/ \ 23 | --mount type=bind,source=${CERTS_DIR}/,target=/opt/keycloak/certs/ \ 24 | quay.io/keycloak/keycloak:20.0 start-dev --import-realm \ 25 | --https-certificate-file=/opt/keycloak/certs/server_devkeycloak_certificate.pem \ 26 | --https-certificate-key-file=/opt/keycloak/certs/server_devkeycloak_key.pem \ 27 | --hostname=devkeycloak --hostname-admin=devkeycloak --https-port=8443 28 | 29 | wait_for_message devkeycloak "Running the server" 30 | print "devkeycloak is running" 31 | -------------------------------------------------------------------------------- /bin/devkeycloak/token: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | 4 | CLIENT_ID=${1:?First parameter must be client_id} 5 | CLIENT_SECRET=${2:?Second parameter must be the client_secret} 6 | 7 | TOKEN=$(curl -k --silent --location --request POST 'https://localhost:8443/realms/dev/protocol/openid-connect/token' \ 8 | --header 'Content-Type: application/x-www-form-urlencoded' \ 9 | --data-urlencode client_id=${CLIENT_ID} \ 10 | --data-urlencode client_secret=${CLIENT_SECRET} \ 11 | --data-urlencode 'grant_type=client_credentials') 12 | 13 | jq -r .access_token <<< "$TOKEN" 14 | -------------------------------------------------------------------------------- /bin/jwt_token: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | ROOT=$SCRIPT/../ 6 | $SCRIPT/jwt_token.py $ROOT/jwts/${1:?jwt token json file} ${2:?key name} $ROOT/conf/${3:?name of the private key file} \ 7 | $ROOT/conf/${4:?name of the public key file} ${5:-some-client} ${6:-True} 8 | -------------------------------------------------------------------------------- /bin/jwt_token.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import jwt 4 | import time 5 | import sys 6 | import json 7 | from datetime import datetime 8 | from datetime import timedelta 9 | 10 | jwt_file_name = key_name = sys.argv[1] 11 | key_name = sys.argv[2] 12 | private_key = open(sys.argv[3], "r").read() 13 | public_key = open(sys.argv[4], "r").read() 14 | client_id = sys.argv[5] 15 | include_kid = sys.argv[6] 16 | 17 | JWT = """{ 18 | "scope": [ 19 | "rabbitmq.write:*/*/*", 20 | "rabbitmq.configure:*/*/*", 21 | "rabbitmq.read:*/*/*" 22 | ], 23 | "extra_scope": "rabbitmq.tag:management", 24 | "aud": [ 25 | "rabbitmq" 26 | ] 27 | }""" 28 | 29 | with open(jwt_file_name) as json_file: 30 | decoded_jwt = json.load(json_file) 31 | 32 | #decoded_jwt = json.loads(JWT) 33 | #decoded_jwt["client_id"] = client_id 34 | #decoded_jwt["cid"] = client_id 35 | #decoded_jwt["sub"] = client_id 36 | 37 | HEADERS={"kid": key_name} 38 | if include_kid == "False" : HEADERS={} 39 | 40 | encoded = jwt.encode(decoded_jwt, private_key, algorithm="RS256", headers=HEADERS) 41 | print(encoded) 42 | -------------------------------------------------------------------------------- /bin/keycloak/curl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | URL=${1:?First parameter must be the url} 7 | CLIENT_ID=${2:?Second parameter must be client_id} 8 | CLIENT_SECRET=${3:?Third parameter must be the client_secret} 9 | REALM=${4:?Forth parameter must be the realm} 10 | 11 | ACCESS_TOKEN=$($SCRIPT/token ${CLIENT_ID} ${CLIENT_SECRET} ${REALM}) 12 | 13 | curl -k -u :$ACCESS_TOKEN $URL 14 | -------------------------------------------------------------------------------- /bin/keycloak/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ! -z "${DEBUG}" ]]; then 4 | set -x 5 | fi 6 | 7 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 8 | 9 | ROOT=$SCRIPT/../.. 10 | CONF_DIR=${ROOT}/conf/keycloak 11 | CERTS_DIR=${CONF_DIR}/certs 12 | 13 | source $SCRIPT/../common 14 | 15 | ensure_docker_network 16 | kill_container_if_exist keycloak 17 | 18 | generate-ca-server-client-kpi keycloak $CERTS_DIR 19 | 20 | begin "Running keycloack docker image ..." 21 | 22 | docker run \ 23 | --detach \ 24 | --name keycloak --net rabbitmq_net \ 25 | --publish 8080:8080 \ 26 | --publish 8443:8443 \ 27 | --env KEYCLOAK_ADMIN=admin \ 28 | --env KEYCLOAK_ADMIN_PASSWORD=admin \ 29 | --mount type=bind,source=${ROOT}/conf/keycloak/import/,target=/opt/keycloak/data/import/ \ 30 | --mount type=bind,source=${CERTS_DIR}/,target=/opt/keycloak/certs/ \ 31 | quay.io/keycloak/keycloak:20.0 start-dev --import-realm \ 32 | --https-certificate-file=/opt/keycloak/certs/server_keycloak_certificate.pem \ 33 | --https-certificate-key-file=/opt/keycloak/certs/server_keycloak_key.pem 34 | 35 | wait_for_message keycloak "Running the server" 36 | print "keycloak is running" 37 | -------------------------------------------------------------------------------- /bin/keycloak/token: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | 4 | CLIENT_ID=${1:?First parameter must be client_id} 5 | CLIENT_SECRET=${2:?Second parameter must be the client_secret} 6 | REALM=${3:?Third parameter must be the realm} 7 | 8 | URL=https://localhost:8443/realms/${REALM}/protocol/openid-connect/token 9 | TOKEN=$(curl -k $URL --silent --location --request POST \ 10 | --header 'Content-Type: application/x-www-form-urlencoded' \ 11 | --data-urlencode client_id=${CLIENT_ID} \ 12 | --data-urlencode client_secret=${CLIENT_SECRET} \ 13 | --data-urlencode 'grant_type=client_credentials') 14 | 15 | jq -r .access_token <<< "$TOKEN" 16 | -------------------------------------------------------------------------------- /bin/oauth2-proxy/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | ROOT=$SCRIPT/../.. 6 | CONF_DIR=${ROOT}/conf/oauth2-proxy 7 | CERTS_DIR=${CONF_DIR}/certs 8 | 9 | source $SCRIPT/../common 10 | 11 | cp -rf ${ROOT}/conf/keycloak/certs/* ${CERTS_DIR} 12 | 13 | PROVIDER_NETWORK=${PROVIDER_NETWORK:-rabbitmq_net} 14 | ensure_docker_network ${PROVIDER_NETWORK} 15 | 16 | docker-compose -f $ROOT/conf/oauth2-proxy/compose.yml down 2>/dev/null || echo "oauth2-proxy was not running" 17 | generate-ca-server-client-kpi oauth2-proxy $CERTS_DIR 18 | 19 | print "Running oauth2-proxy docker image ..." 20 | 21 | export OAUTH2_PROXY_COOKIE_SECRET=`dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_' ; echo` 22 | docker compose -f $ROOT/conf/oauth2-proxy/compose.yml up -d 23 | 24 | wait_for_message oauth2-proxy-oauth2-proxy-1 "Cookie settings" 25 | print "oauth2-proxy is running" 26 | 27 | 28 | -------------------------------------------------------------------------------- /bin/oauth2-proxy/undeploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | ROOT=$SCRIPT/../.. 6 | CONF_DIR=${ROOT}/conf/oauth2-proxy 7 | CERTS_DIR=${CONF_DIR}/certs 8 | 9 | 10 | echo "Stopping oauth2-proxy ..." 11 | 12 | docker compose -f $ROOT/conf/oauth2-proxy/compose.yml down 13 | 14 | 15 | -------------------------------------------------------------------------------- /bin/open_url: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ue 4 | 5 | USERNAME=${1:?First parameter must be the USERNAME} 6 | PASSWORD=${2:?Second parameter must be the PASSWORD} 7 | 8 | echo "Log in as $USERNAME:$PASSWORD with UAA using rabbit_client OAuth client ..." 9 | uaac token owner get test_client $USERNAME -s test_client -p $PASSWORD \ 10 | && echo "Login succeeded. We have the JWT Token" 11 | 12 | echo "Opening Management UI as $USERNAME ... " 13 | token=$(uaac context $USERNAME | awk '/access_token/ { print $2}') 14 | url="http://localhost:15672/#/login?&access_token=$token" 15 | open $url 16 | -------------------------------------------------------------------------------- /bin/portal/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | if [[ ! -z "${DEBUG}" ]]; then 6 | set -x 7 | fi 8 | 9 | ROOT=$SCRIPT/../.. 10 | CONF_DIR=${ROOT}/conf/portal 11 | CERTS_DIR=${CONF_DIR}/certs 12 | 13 | source $SCRIPT/../common 14 | 15 | if [ ! -f ${ROOT}/conf/uaa/certs ]; then 16 | print "Deploy uaa first so that portal can reference its certificates" 17 | fi 18 | 19 | print "Starting portal ..." 20 | 21 | DOCKER_NETWORK=${DOCKER_NETWORK:-rabbitmq_net} 22 | ensure_docker_network ${DOCKER_NETWORK} 23 | kill_container_if_exist portal 24 | 25 | image_tag=($(md5sum $CONF_DIR/package.json)) 26 | if [[ $(docker images -q portal:$image_tag 2> /dev/null) == "" ]]; then 27 | docker build -t portal:$image_tag --target test $CONF_DIR 28 | fi 29 | 30 | generate-ca-server-client-kpi portal $CERTS_DIR 31 | 32 | begin "Running portal docker image portal:${image_tag} ..." 33 | 34 | rm -f ${CONF_DIR}/certs/ca_certs.pem 35 | cat ${ROOT}/conf/uaa/certs/ca_uaa_certificate.pem ${CONF_DIR}/certs/ca_rabbitmq_certificate.pem \ 36 | >> ${CONF_DIR}/certs/ca_certs.pem 37 | 38 | if [[ -f ${ROOT}/conf/portal/certs/ca_proxy_certificate.pem ]]; then 39 | cat ${ROOT}/conf/portal/certs/ca_proxy_certificate.pem >> ${CONF_DIR}/certs/ca_certs.pem 40 | fi 41 | 42 | docker run \ 43 | --detach \ 44 | --name portal \ 45 | --net ${DOCKER_NETWORK} \ 46 | --publish 3000:3000 \ 47 | --env PORT=3000 \ 48 | --env RABBITMQ_URL="https://localhost:15671" \ 49 | --env UAA_URL="https://uaa:8443" \ 50 | --env CLIENT_ID="rabbit_idp_user" \ 51 | --env CLIENT_SECRET="rabbit_idp_user" \ 52 | --env PROXIED_RABBITMQ_URL="https://proxy:9090" \ 53 | --env NODE_EXTRA_CA_CERTS=/etc/portal/ca_certs.pem \ 54 | -v ${CONF_DIR}/certs:/etc/portal \ 55 | -v ${CONF_DIR}:/code/portal \ 56 | portal:${image_tag} run portal 57 | 58 | print "portal is running" 59 | -------------------------------------------------------------------------------- /bin/prodkeycloak/curl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | URL=${1:?First parameter must be the url} 7 | CLIENT_ID=${2:?Second parameter must be client_id} 8 | CLIENT_SECRET=${3:?Third parameter must be the client_secret} 9 | ACCESS_TOKEN=$($SCRIPT/token ${CLIENT_ID} ${CLIENT_SECRET}) 10 | 11 | curl -k -u :$ACCESS_TOKEN $URL 12 | -------------------------------------------------------------------------------- /bin/prodkeycloak/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | ROOT=$SCRIPT/../.. 5 | CONF_DIR=${ROOT}/conf/multi-keycloak 6 | CERTS_DIR=${CONF_DIR}/certs 7 | 8 | ensure_docker_network 9 | kill_container_if_exist prodkeycloak 10 | 11 | generate-ca-server-client-kpi prodkeycloak $CERTS_DIR 12 | 13 | echo "Running prodkeycloak docker image ..." 14 | 15 | docker run \ 16 | --detach \ 17 | --name prodkeycloak --net rabbitmq_net \ 18 | --publish 8082:8080 \ 19 | --publish 8442:8442 \ 20 | --env KEYCLOAK_ADMIN=admin \ 21 | --env KEYCLOAK_ADMIN_PASSWORD=admin \ 22 | --mount type=bind,source=${CONF_DIR}/prod_import/,target=/opt/keycloak/data/import/ \ 23 | --mount type=bind,source=${CERTS_DIR}/,target=/opt/keycloak/certs/ \ 24 | quay.io/keycloak/keycloak:20.0 start-dev --import-realm \ 25 | --https-certificate-file=/opt/keycloak/certs/server_prodkeycloak_certificate.pem \ 26 | --https-certificate-key-file=/opt/keycloak/certs/server_prodkeycloak_key.pem \ 27 | --hostname=prodkeycloak --hostname-admin=prodkeycloak --https-port=8442 28 | 29 | wait_for_message prodkeycloak "Running the server" 30 | print "prodkeycloak is running" 31 | -------------------------------------------------------------------------------- /bin/prodkeycloak/token: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | 4 | CLIENT_ID=${1:?First parameter must be client_id} 5 | CLIENT_SECRET=${2:?Second parameter must be the client_secret} 6 | 7 | TOKEN=$(curl -k --silent --location --request POST 'https://localhost:8442/realms/prod/protocol/openid-connect/token' \ 8 | --header 'Content-Type: application/x-www-form-urlencoded' \ 9 | --data-urlencode client_id=${CLIENT_ID} \ 10 | --data-urlencode client_secret=${CLIENT_SECRET} \ 11 | --data-urlencode 'grant_type=client_credentials') 12 | 13 | jq -r .access_token <<< "$TOKEN" 14 | -------------------------------------------------------------------------------- /bin/proxy/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | if [[ ! -z "${DEBUG}" ]]; then 6 | set -x 7 | fi 8 | 9 | ROOT=$SCRIPT/../.. 10 | CONF_DIR=${ROOT}/conf/portal 11 | CERTS_DIR=${CONF_DIR}/certs 12 | 13 | source $SCRIPT/../common 14 | 15 | if [ ! -f ${ROOT}/conf/uaa/certs ]; then 16 | print "Deploy uaa first so that portal can reference its certificates" 17 | fi 18 | 19 | print "Starting proxy ..." 20 | 21 | DOCKER_NETWORK=${DOCKER_NETWORK:-rabbitmq_net} 22 | ensure_docker_network ${DOCKER_NETWORK} 23 | kill_container_if_exist proxy 24 | 25 | image_tag=($(md5sum $CONF_DIR/package.json)) 26 | if [[ $(docker images -q portal:$image_tag 2> /dev/null) == "" ]]; then 27 | docker build -t portal:$image_tag --target test $CONF_DIR 28 | fi 29 | 30 | generate-ca-server-client-kpi proxy $CERTS_DIR 31 | 32 | begin "Running proxy docker image portal:${image_tag} ..." 33 | 34 | rm -f ${CONF_DIR}/certs/ca_certs.pem 35 | cat ${ROOT}/conf/uaa/certs/ca_uaa_certificate.pem ${CONF_DIR}/certs/ca_rabbitmq_certificate.pem \ 36 | >> ${CONF_DIR}/certs/ca_certs.pem 37 | 38 | docker run \ 39 | --detach \ 40 | --name proxy \ 41 | --net ${DOCKER_NETWORK} \ 42 | --publish 9090:9090 \ 43 | --env PORT=9090 \ 44 | --env RABBITMQ_URL="https://rabbitmq:15671" \ 45 | --env UAA_URL="https://uaa:8443" \ 46 | --env CLIENT_ID="rabbit_idp_user" \ 47 | --env CLIENT_SECRET="rabbit_idp_user" \ 48 | --env NODE_EXTRA_CA_CERTS=/etc/proxy/ca_certs.pem \ 49 | -v ${CONF_DIR}/certs:/etc/proxy \ 50 | -v ${CONF_DIR}:/code/portal \ 51 | portal:${image_tag} run proxy 52 | 53 | print "proxy is running" 54 | -------------------------------------------------------------------------------- /bin/run-amqp1_0-client: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CLIENT_ID=${1:?First parameter must be client id} 4 | 5 | token=$(uaac context $CLIENT_ID | awk '/access_token/ { print $2}') 6 | queue=${QUEUE:-q-test-queue} 7 | 8 | shift 1 9 | 10 | echo "Launching AMQP1.0-client with a token for Oauth Client $CLIENT_ID " 11 | echo "QUEUE: $queue" 12 | echo "TOKEN: $token" 13 | 14 | docker network inspect rabbitmq_net >/dev/null 2>&1 || docker network create rabbitmq_net 15 | docker rm -f amqp1_0-$CLIENT_ID 2>/dev/null || echo "amqp1_0-$CLIENT_ID was not running" 16 | 17 | docker run --rm --name amqp1_0-$CLIENT_ID \ 18 | --network rabbitmq_net \ 19 | --env USERNAME=" " \ 20 | --env PASSWORD=$token \ 21 | --env QUEUE=$queue \ 22 | amqp1_0-client $@ 23 | -------------------------------------------------------------------------------- /bin/run-demo-oauth-cf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CLIENT_ID=${1:?First parameter must be the client_id} 4 | CLIENT_SECRET=${2:?Second parameter must be the client_secret} 5 | 6 | read -r -d '' VCAP_SERVICES </dev/null 2>&1 || docker network create rabbitmq_net 27 | docker rm -f spring-demo-oauth 2>/dev/null || echo "spring-demo-oauth was not running" 28 | 29 | echo "Launching demo-oauth-rabbitmq with client_id $CLIENT_ID simulating CloudFoundry environment " 30 | docker run -d --rm \ 31 | --network rabbitmq_net \ 32 | --name spring-demo-oauth \ 33 | -v $PWD/demo-oauth-rabbitmq/target:/app \ 34 | -e "SPRING_PROFILES_ACTIVE=Cloud" \ 35 | -e "VCAP_APPLICATION='{\"application_name\":spring-demo-oauth}'" \ 36 | -e "VCAP_SERVICES=$VCAP_SERVICES" \ 37 | -p 8081:8080 \ 38 | openjdk:8-jdk \ 39 | java -jar /app/demo-oauth-rabbitmq-0.0.1-SNAPSHOT.jar 40 | -------------------------------------------------------------------------------- /bin/run-jms-client: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CLIENT_ID=${1:?First parameter must be client id} 4 | 5 | token=$(uaac context $CLIENT_ID | awk '/access_token/ { print $2}') 6 | hostname=${HOST:-rabbitmq} 7 | queue=${QUEUE:-q-test-queue} 8 | 9 | shift 1 10 | 11 | echo "Launching JMS-client with a token for Oauth Client $CLIENT_ID " 12 | echo "HOSTNAME: $hostname" 13 | echo "QUEUE: $queue" 14 | echo "TOKEN: $token" 15 | 16 | docker network inspect rabbitmq_net >/dev/null 2>&1 || docker network create rabbitmq_net 17 | docker rm -f jms-$CLIENT_ID 2>/dev/null || echo "$CLIENT_ID was not running" 18 | 19 | docker run --rm --name $CLIENT_ID \ 20 | --network rabbitmq_net \ 21 | --env HOSTNAME=$hostname \ 22 | --env TOKEN=$token \ 23 | --env QUEUE=$queue \ 24 | jms-client $@ 25 | -------------------------------------------------------------------------------- /bin/run-perftest: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CLIENT_ID=${1:?First parameter must be client id} 4 | 5 | if [ -z "$TOKEN" ]; then 6 | echo "Getting token from UAA ..." 7 | TOKEN=$(uaac context $CLIENT_ID | awk '/access_token/ { print $2}') 8 | fi 9 | echo "Using token ${TOKEN}" 10 | 11 | url="amqp://:$TOKEN@rabbitmq:5672/%2F" 12 | 13 | shift 1 14 | 15 | echo "Launching $CLIENT_ID app with arguments: $@ " 16 | echo " and url: $url" 17 | 18 | docker network inspect rabbitmq_net >/dev/null 2>&1 || docker network create rabbitmq_net 19 | docker rm -f $CLIENT_ID 2>/dev/null || echo "$CLIENT_ID was not running" 20 | 21 | docker run -d --rm \ 22 | --network rabbitmq_net \ 23 | --name $CLIENT_ID \ 24 | pivotalrabbitmq/perf-test:latest \ 25 | --uri $url \ 26 | $@ 27 | -------------------------------------------------------------------------------- /bin/uaa/curl_url: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CONTEXT=${1:?First parameter must be the uaac context name. Run uaac contexts to find out which contexts are available} 4 | URL=${2:?Second parameter must be the url to curl} 5 | 6 | token=$(uaac context $CONTEXT | awk '/access_token/ { print $2}') 7 | echo "token => $token" 8 | 9 | curl -k -u :$token $URL 10 | -------------------------------------------------------------------------------- /bin/uaa/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | ROOT=$SCRIPT/../.. 7 | UAA_IMAGE_TAG=${UAA_IMAGE_TAG:-75.21.0} 8 | UAA_IMAGE_NAME=${UAA_IMAGE_NAME:-cloudfoundry/uaa} 9 | UAA_MODE=${UAA_MODE:-"uaa"} 10 | CONF_DIR=${ROOT}/conf/${UAA_MODE} 11 | CERTS_DIR=${CONF_DIR}/certs 12 | 13 | source $SCRIPT/../common 14 | 15 | function generate-keystore-if-required { 16 | if [[ ! -f "${CERTS_DIR}/uaa.jks " ]]; then 17 | keytool -importkeystore \ 18 | -destkeystore ${CERTS_DIR}/uaa.jks \ 19 | -srckeystore ${CERTS_DIR}/server_uaa.p12 \ 20 | -deststoretype pkcs12 \ 21 | -srcstoretype pkcs12 \ 22 | -alias 1 \ 23 | -destalias uaa-tls \ 24 | -deststorepass foobar \ 25 | -destkeypass foobar \ 26 | -srcstorepass "" \ 27 | -srckeypass "" \ 28 | -noprompt 29 | fi 30 | } 31 | 32 | function deploy { 33 | echo "Running ${UAA_IMAGE_NAME}:${UAA_IMAGE_TAG} docker image with .." 34 | 35 | docker run \ 36 | --detach \ 37 | --name uaa \ 38 | --net rabbitmq_net \ 39 | --publish 8080:8080 \ 40 | --publish 8443:8443 \ 41 | -v ${CONF_DIR}:/uaa \ 42 | -v ${CONF_DIR}/server.xml:/layers/paketo-buildpacks_apache-tomcat/catalina-base/conf/server.xml \ 43 | --env UAA_CONFIG_PATH="/uaa" \ 44 | --env JAVA_OPTS="-Djava.security.policy=unlimited -Djava.security.egd=file:/dev/./urandom" \ 45 | "${UAA_IMAGE_NAME}:${UAA_IMAGE_TAG}" 46 | } 47 | 48 | ensure_docker_network 49 | kill_container_if_exist uaa 50 | generate-ca-server-client-kpi uaa $CERTS_DIR 51 | generate-keystore-if-required 52 | deploy 53 | -------------------------------------------------------------------------------- /bin/uaa/token: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | CLIENT_ID=${1:?First parameter must be client_id} 5 | CLIENT_SECRET=${2:?Second parameter must be the client_secret} 6 | 7 | TOKEN=$(curl -k --silent --location --request POST 'https://localhost:8443/oauth/token' \ 8 | --header 'Content-Type: application/x-www-form-urlencoded' \ 9 | --data-urlencode client_id=${CLIENT_ID} \ 10 | --data-urlencode client_secret=${CLIENT_SECRET} \ 11 | --data-urlencode 'grant_type=client_credentials') 12 | 13 | jq -r .access_token <<< "$TOKEN" 14 | -------------------------------------------------------------------------------- /conf/auth0/rabbitmq.conf.tmpl: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | log.console.level = debug 4 | 5 | management.oauth_enabled = true 6 | management.oauth_client_id = {Client ID} 7 | management.oauth_scopes = openid profile rabbitmq.tag:administrator 8 | 9 | auth_oauth2.resource_server_id = rabbitmq 10 | auth_oauth2.issuer = {Domain} 11 | auth_oauth2.https.hostname_verification = wildcard 12 | -------------------------------------------------------------------------------- /conf/auth0/requires-tls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitmq/rabbitmq-oauth2-tutorial/e1b959370ab7b626a0cb7635957be8ea623a3bac/conf/auth0/requires-tls -------------------------------------------------------------------------------- /conf/auth0/tls.conf: -------------------------------------------------------------------------------- 1 | management.ssl.port = 15671 2 | management.ssl.cacertfile = /certs/ca_rabbitmq_certificate.pem 3 | management.ssl.certfile = /certs/server_rabbitmq_certificate.pem 4 | management.ssl.keyfile = /certs/server_rabbitmq_key.pem 5 | management.ssl.fail_if_no_peer_cert = false 6 | management.ssl.client_renegotiation = false 7 | management.ssl.secure_renegotiate = true 8 | management.ssl.honor_ecc_order = true 9 | management.ssl.honor_cipher_order = true -------------------------------------------------------------------------------- /conf/enabled_plugins: -------------------------------------------------------------------------------- 1 | [rabbitmq_stream_management,rabbitmq_auth_backend_oauth2,rabbitmq_amqp1_0,rabbitmq_web_mqtt]. 2 | -------------------------------------------------------------------------------- /conf/entra/rabbitmq.conf.tmpl: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | log.console.level = debug 4 | 5 | management.oauth_enabled = true 6 | management.oauth_client_id = {Application(client) ID} 7 | management.oauth_scopes = openid profile api://{Application(client) ID}/rabbitmq 8 | 9 | auth_oauth2.resource_server_id = {Application(client) ID} 10 | auth_oauth2.additional_scopes_key = roles 11 | auth_oauth2.jwks_url = https://login.microsoftonline.com/{Directory (tenant) ID}/discovery/v2.0/keys 12 | auth_oauth2.preferred_username_claims.1 = name 13 | auth_oauth2.preferred_username_claims.2 = preferred_username 14 | -------------------------------------------------------------------------------- /conf/entra/requires-tls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitmq/rabbitmq-oauth2-tutorial/e1b959370ab7b626a0cb7635957be8ea623a3bac/conf/entra/requires-tls -------------------------------------------------------------------------------- /conf/entra/tls.conf: -------------------------------------------------------------------------------- 1 | management.ssl.port = 15671 2 | management.ssl.cacertfile = /certs/ca_rabbitmq_certificate.pem 3 | management.ssl.certfile = /certs/server_rabbitmq_certificate.pem 4 | management.ssl.keyfile = /certs/server_rabbitmq_key.pem 5 | management.ssl.fail_if_no_peer_cert = false 6 | management.ssl.client_renegotiation = false 7 | management.ssl.secure_renegotiate = true 8 | management.ssl.honor_ecc_order = true 9 | management.ssl.honor_cipher_order = true -------------------------------------------------------------------------------- /conf/google/advanced.config: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | rabbitmq_auth_backend_oauth2, 4 | [ 5 | {resource_server_id, <<".apps.googleusercontent.com">>}, 6 | {scope_aliases, #{ 7 | <<"https://www.googleapis.com/auth/userinfo.profile">> => [ 8 | <<"rabbitmq.read:*/*">>, 9 | <<"rabbitmq.write:*/*">>, 10 | <<"rabbitmq.configure:*/*">>, 11 | <<"rabbitmq.tag:administrator">> 12 | ] 13 | }} 14 | ]} 15 | ]. 16 | -------------------------------------------------------------------------------- /conf/google/rabbitmq.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | management.oauth_enabled = true 4 | management.oauth_client_id = .apps.googleusercontent.com 5 | management.oauth_client_secret = 6 | management.oauth_scopes = openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/service.management 7 | management.oauth_provider_url = https://accounts.google.com 8 | 9 | auth_oauth2.resource_server_id = .apps.googleusercontent.com 10 | auth_oauth2.preferred_username_claims.1 = user_name 11 | auth_oauth2.jwks_url = https://www.googleapis.com/oauth2/v3/certs 12 | auth_oauth2.scope_prefix = rabbitmq. 13 | -------------------------------------------------------------------------------- /conf/keycloak/rabbitmq.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | log.console.level = debug 4 | 5 | management.oauth_enabled = true 6 | management.oauth_client_id = rabbitmq-client-code 7 | management.oauth_scopes = openid profile rabbitmq.tag:administrator 8 | 9 | auth_oauth2.resource_server_id = rabbitmq 10 | auth_oauth2.preferred_username_claims.1 = user_name 11 | auth_oauth2.issuer = https://keycloak:8443/realms/test 12 | auth_oauth2.https.cacertfile = /certs/ca_keycloak_certificate.pem 13 | auth_oauth2.additional_scopes_key = extra_scope 14 | -------------------------------------------------------------------------------- /conf/keycloak/signing-key/signing-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2dP+vRn+Kj+S/oGd49kq 3 | 6+CKNAduCC1raLfTH7B3qjmZYm45yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhK 4 | IdcIWadhqDzdtn1hj/22iUwrhH0bd475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2 5 | B9q9KFBmo4Ahh/6+d4wM1rH9kxl0RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF 6 | 2cr3wQwCfF1qVu4eAVNVfxfy/uEvG3Q7x005P3TcK+QcYgJxav3lictSi5dyWLgG 7 | QAvkknWitpRK8KVLypEj5WKej6CF8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7 8 | VwIDAQAB 9 | -----END PUBLIC KEY----- 10 | 11 | -------------------------------------------------------------------------------- /conf/multi-keycloak/rabbitmq.scenario1.basic.conf: -------------------------------------------------------------------------------- 1 | ## RabbitMQ configuration with 2 oauth2 resources, rabbit_prod and rabbit_dev, 2 | ## rather than a single resource_server_id 3 | ## Also, each resource is owned by its own oauth provider, i.e. RabbitMQ is 4 | ## accessed by users and clients from two different providers using their dedicated 5 | ## resource_server_id. 6 | 7 | log.console.level = debug 8 | 9 | auth_backends.1 = rabbit_auth_backend_oauth2 10 | 11 | # Common auth_oauth2 settings for all resources 12 | auth_oauth2.preferred_username_claims.1 = preferred_username 13 | auth_oauth2.preferred_username_claims.2 = user_name 14 | auth_oauth2.preferred_username_claims.3 = email 15 | auth_oauth2.scope_prefix = rabbitmq. 16 | 17 | # OAuth provider settings for all resources 18 | auth_oauth2.issuer = https://keycloak:8443/realms/test 19 | auth_oauth2.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem 20 | auth_oauth2.https.peer_verification = verify_peer 21 | auth_oauth2.https.hostname_verification = wildcard 22 | 23 | ## Resource servers hosted by this rabbitmq instance 24 | auth_oauth2.resource_servers.1.id = rabbit_prod 25 | auth_oauth2.resource_servers.2.id = rabbit_dev 26 | 27 | # Common management setting for all resources 28 | management.oauth_enabled = true 29 | management.oauth_scopes = openid profile rabbitmq.tag:administrator rabbitmq.tag:management 30 | 31 | ## Management ui settings for each declared resource server 32 | management.oauth_resource_servers.1.id = rabbit_prod 33 | management.oauth_resource_servers.1.oauth_client_id = rabbit_prod_mgt_ui 34 | 35 | management.oauth_resource_servers.2.id = rabbit_dev 36 | management.oauth_resource_servers.2.oauth_client_id = rabbit_dev_mgt_ui 37 | -------------------------------------------------------------------------------- /conf/multi-keycloak/rabbitmq.scenario1.conf: -------------------------------------------------------------------------------- 1 | ## RabbitMQ configuration with 2 oauth2 resources, rabbit_prod and rabbit_dev, 2 | ## rather than a single resource_server_id 3 | ## Also, each resource is owned by its own oauth provider, i.e. RabbitMQ is 4 | ## accessed by users and clients from two different providers using their dedicated 5 | ## resource_server_id. 6 | 7 | log.console.level = debug 8 | 9 | auth_backends.1 = rabbit_auth_backend_oauth2 10 | 11 | # Common auth_oauth2 settings for all resources 12 | auth_oauth2.preferred_username_claims.1 = preferred_username 13 | auth_oauth2.preferred_username_claims.2 = user_name 14 | auth_oauth2.preferred_username_claims.3 = email 15 | auth_oauth2.scope_prefix = rabbitmq. 16 | auth_oauth2.default_oauth_provider = keycloak 17 | 18 | ## Resource servers hosted by this rabbitmq instance 19 | auth_oauth2.resource_servers.1.id = rabbit_prod 20 | auth_oauth2.resource_servers.2.id = rabbit_dev 21 | 22 | ## Oauth providers 23 | auth_oauth2.oauth_providers.keycloak.issuer = https://keycloak:8443/realms/test 24 | auth_oauth2.oauth_providers.keycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem 25 | auth_oauth2.oauth_providers.keycloak.https.verify = verify_peer 26 | auth_oauth2.oauth_providers.keycloak.https.hostname_verification = wildcard 27 | 28 | 29 | # Common management setting for all resources 30 | management.oauth_enabled = true 31 | 32 | ## Management ui settings for each declared resource server 33 | management.oauth_resource_servers.1.id = rabbit_prod 34 | management.oauth_resource_servers.1.oauth_client_id = rabbit_prod_mgt_ui 35 | management.oauth_resource_servers.1.label = RabbitMQ Production 36 | management.oauth_resource_servers.1.oauth_scopes = openid profile rabbitmq.tag:administrator 37 | 38 | management.oauth_resource_servers.2.id = rabbit_dev 39 | management.oauth_resource_servers.2.oauth_client_id = rabbit_dev_mgt_ui 40 | management.oauth_resource_servers.2.label = RabbitMQ Development 41 | management.oauth_resource_servers.2.oauth_scopes = openid profile rabbitmq.tag:management 42 | -------------------------------------------------------------------------------- /conf/multi-keycloak/rabbitmq.scenario2.conf: -------------------------------------------------------------------------------- 1 | ## RabbitMQ configuration with 2 oauth2 resources, rabbit_prod and rabbit_dev, 2 | ## rather than a single resource_server_id 3 | ## Also, each resource is owned by its own oauth provider, i.e. RabbitMQ is 4 | ## accessed by users and clients from two different providers using their dedicated 5 | ## resource_server_id. 6 | 7 | log.console.level = debug 8 | 9 | auth_backends.1 = rabbit_auth_backend_oauth2 10 | 11 | # Common auth_oauth2 settings for all resources 12 | auth_oauth2.preferred_username_claims.1 = preferred_username 13 | auth_oauth2.preferred_username_claims.2 = user_name 14 | auth_oauth2.preferred_username_claims.3 = email 15 | auth_oauth2.scope_prefix = rabbitmq. 16 | 17 | ## Resource servers hosted by this rabbitmq instance 18 | auth_oauth2.resource_servers.1.id = rabbit_prod 19 | auth_oauth2.resource_servers.1.oauth_provider_id = prodkeycloak 20 | auth_oauth2.resource_servers.2.id = rabbit_dev 21 | auth_oauth2.resource_servers.2.oauth_provider_id = devkeycloak 22 | 23 | ## Oauth providers 24 | auth_oauth2.oauth_providers.devkeycloak.issuer = https://keycloak:8443/realms/dev 25 | auth_oauth2.oauth_providers.devkeycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem 26 | auth_oauth2.oauth_providers.devkeycloak.https.verify = verify_peer 27 | auth_oauth2.oauth_providers.devkeycloak.https.hostname_verification = wildcard 28 | 29 | auth_oauth2.oauth_providers.prodkeycloak.issuer = https://keycloak:8443/realms/prod 30 | auth_oauth2.oauth_providers.prodkeycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem 31 | auth_oauth2.oauth_providers.prodkeycloak.https.verify = verify_peer 32 | auth_oauth2.oauth_providers.prodkeycloak.https.hostname_verification = wildcard 33 | 34 | 35 | # Common management setting for all resources 36 | management.oauth_enabled = true 37 | 38 | ## Management ui settings for each declared resource server 39 | management.oauth_resource_servers.1.id = rabbit_prod 40 | management.oauth_resource_servers.1.oauth_client_id = rabbit_prod_mgt_ui 41 | management.oauth_resource_servers.1.label = RabbitMQ Production 42 | management.oauth_resource_servers.1.oauth_scopes = openid profile rabbitmq.tag:administrator 43 | 44 | management.oauth_resource_servers.2.id = rabbit_dev 45 | management.oauth_resource_servers.2.oauth_client_id = rabbit_dev_mgt_ui 46 | management.oauth_resource_servers.2.label = RabbitMQ Development 47 | management.oauth_resource_servers.2.oauth_scopes = openid profile rabbitmq.tag:management 48 | -------------------------------------------------------------------------------- /conf/multi-keycloak/rabbitmq.scenario3.conf: -------------------------------------------------------------------------------- 1 | ## RabbitMQ configuration with 2 oauth2 resources, rabbit_prod and rabbit_dev, 2 | ## rather than a single resource_server_id 3 | ## Also, each resource is owned by its own oauth provider, i.e. RabbitMQ is 4 | ## accessed by users and clients from two different providers using their dedicated 5 | ## resource_server_id. 6 | 7 | log.console.level = debug 8 | 9 | auth_backends.1 = rabbit_auth_backend_oauth2 10 | 11 | # Common auth_oauth2 settings for all resources 12 | auth_oauth2.preferred_username_claims.1 = preferred_username 13 | auth_oauth2.preferred_username_claims.2 = user_name 14 | auth_oauth2.preferred_username_claims.3 = email 15 | auth_oauth2.scope_prefix = rabbitmq. 16 | 17 | ## Resource servers hosted by this rabbitmq instance 18 | auth_oauth2.resource_servers.1.id = rabbit_prod 19 | auth_oauth2.resource_servers.1.oauth_provider_id = prodkeycloak 20 | auth_oauth2.resource_servers.2.id = rabbit_dev 21 | auth_oauth2.resource_servers.2.oauth_provider_id = devkeycloak 22 | 23 | ## Oauth providers 24 | auth_oauth2.oauth_providers.devkeycloak.issuer = https://devkeycloak:8443/realms/dev 25 | auth_oauth2.oauth_providers.devkeycloak.https.cacertfile = /etc/rabbitmq/multi-keycloak-ca_certificate.pem 26 | auth_oauth2.oauth_providers.devkeycloak.https.verify = verify_peer 27 | auth_oauth2.oauth_providers.devkeycloak.https.hostname_verification = wildcard 28 | 29 | auth_oauth2.oauth_providers.prodkeycloak.issuer = https://prodkeycloak:8442/realms/prod 30 | auth_oauth2.oauth_providers.prodkeycloak.https.cacertfile = /etc/rabbitmq/multi-keycloak-ca_certificate.pem 31 | auth_oauth2.oauth_providers.prodkeycloak.https.verify = verify_peer 32 | auth_oauth2.oauth_providers.prodkeycloak.https.hostname_verification = wildcard 33 | 34 | 35 | # Common management setting for all resources 36 | management.oauth_enabled = true 37 | 38 | ## Management ui settings for each declared resource server 39 | management.oauth_resource_servers.1.id = rabbit_prod 40 | management.oauth_resource_servers.1.oauth_client_id = rabbit_prod_mgt_ui 41 | management.oauth_resource_servers.1.label = RabbitMQ Production 42 | management.oauth_resource_servers.1.oauth_scopes = openid profile rabbitmq.tag:administrator 43 | 44 | management.oauth_resource_servers.2.id = rabbit_dev 45 | management.oauth_resource_servers.2.oauth_client_id = rabbit_dev_mgt_ui 46 | management.oauth_resource_servers.2.label = RabbitMQ Development 47 | management.oauth_resource_servers.2.oauth_scopes = openid profile rabbitmq.tag:management 48 | -------------------------------------------------------------------------------- /conf/multi-keycloak/signing-key/signing-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2dP+vRn+Kj+S/oGd49kq 3 | 6+CKNAduCC1raLfTH7B3qjmZYm45yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhK 4 | IdcIWadhqDzdtn1hj/22iUwrhH0bd475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2 5 | B9q9KFBmo4Ahh/6+d4wM1rH9kxl0RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF 6 | 2cr3wQwCfF1qVu4eAVNVfxfy/uEvG3Q7x005P3TcK+QcYgJxav3lictSi5dyWLgG 7 | QAvkknWitpRK8KVLypEj5WKej6CF8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7 8 | VwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /conf/oauth2-proxy/alpha-config.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | BindAddress: 0.0.0.0:4180 3 | SecureBindAddress: 0.0.0.0:443 4 | TLS: 5 | Key: 6 | FromFile: /etc/oauth2-proxy/certs/server_oauth2-proxy_key.pem 7 | Cert: 8 | FromFile: /etc/oauth2-proxy/certs/server_oauth2-proxy_certificate.pem 9 | 10 | upstreamConfig: 11 | upstreams: 12 | - id: rabbitmq 13 | path: / 14 | uri: http://rabbitmq:15672 15 | injectRequestHeaders: 16 | - name: Authorization 17 | values: 18 | - claim: access_token 19 | prefix: 'Bearer ' 20 | providers: 21 | - provider: keycloak-oidc 22 | id: keycloak-oidc 23 | clientSecret: nt6pmZMeyrgzYgkg2MLgZQZxLveRMW5M 24 | clientID: rabbitmq-proxy-client-tls 25 | code_challenge_method: S256 26 | scope: "email openid profile rabbitmq.tag:administrator" 27 | skipClaimsFromProfileURL: true 28 | caFiles: 29 | - /etc/keycloak/certs/ca_keycloak_certificate.pem 30 | oidcConfig: 31 | issuerURL: https://keycloak:8443/realms/test 32 | insecureSkipNonce: true 33 | audienceClaims: 34 | - aud 35 | emailClaim: sub 36 | userIDClaim: user_name 37 | -------------------------------------------------------------------------------- /conf/oauth2-proxy/compose.yml: -------------------------------------------------------------------------------- 1 | 2 | networks: 3 | rabbitmq_net: 4 | name: rabbitmq_net 5 | external: true 6 | 7 | services: 8 | oauth2-proxy: 9 | image: bitnami/oauth2-proxy:7.7.1 10 | networks: 11 | - rabbitmq_net 12 | command: --alpha-config /etc/oauth2-proxy/alpha-config.yaml --cookie-secure=true 13 | volumes: 14 | - "./:/etc/oauth2-proxy" 15 | - "../keycloak:/etc/keycloak" 16 | environment: 17 | OAUTH2_PROXY_COOKIE_SECRET: ${OAUTH2_PROXY_COOKIE_SECRET} 18 | OAUTH2_PROXY_EMAIL_DOMAINS: "*" 19 | OAUTH2_PROXY_COOKIE_DOMAINS: "" 20 | OAUTH2_PROXY_WHITELIST_DOMAINS: "*" 21 | OAUTH2_PROXY_COOKIE_CSRF_PER_REQUEST: "true" 22 | OAUTH2_PROXY_COOKIE_CSRF_EXPIRE: "5m" 23 | OAUTH2_PROXY_REDIRECT_URL: https://oauth2-proxy:8442/oauth2/callback 24 | OAUTH2_PROXY_TLS_KEY_FILE: /etc/oauth2-proxy/certs/server_oauth2-proxy_key.pem 25 | OAUTH2_PROXY_TLS_CERT_FILE: /etc/oauth2-proxy/certs/server_oauth2-proxy_certificate.pem 26 | ports: 27 | - 8442:443 28 | -------------------------------------------------------------------------------- /conf/oauth2-proxy/rabbitmq.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | log.default.level = debug 4 | log.console.level = debug 5 | 6 | management.oauth_enabled = true 7 | management.oauth_initiated_logon_type = idp_initiated 8 | management.oauth_provider_url = https://oauth2-proxy:8442 9 | 10 | auth_oauth2.resource_server_id = rabbitmq 11 | auth_oauth2.jwks_uri = https://keycloak:8443/realms/test/protocol/openid-connect/certs 12 | auth_oauth2.end_session_endpoint = https://oauth2-proxy:8442/oauth2/sign_out?rd=https://keycloak:8443/realms/test/protocol/openid-connect/logout 13 | auth_oauth2.https.cacertfile = /etc/oauth2-proxy/certs/ca_keycloak_certificate.pem 14 | auth_oauth2.preferred_username_claims.1 = preferred_username 15 | auth_oauth2.verify_aud = false 16 | -------------------------------------------------------------------------------- /conf/oauth2-proxy/signing-key/signing-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2dP+vRn+Kj+S/oGd49kq6+CKNAduCC1raLfTH7B3qjmZYm45yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhKIdcIWadhqDzdtn1hj/22iUwrhH0bd475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2B9q9KFBmo4Ahh/6+d4wM1rH9kxl0RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF2cr3wQwCfF1qVu4eAVNVfxfy/uEvG3Q7x005P3TcK+QcYgJxav3lictSi5dyW 3 | LgGQAvkknWitpRK8KVLypEj5WKej6CF8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7VwIDAQAB 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /conf/okta/advanced.config: -------------------------------------------------------------------------------- 1 | [ 2 | %% Set a resource server ID. Will require all scopes to be prefixed with `rabbitmq.` 3 | {rabbitmq_auth_backend_oauth2, [ 4 | {scope_aliases, #{ 5 | <<"admin">> => [ 6 | <<"okta.read:*/*">>, 7 | <<"okta.write:*/*">>, 8 | <<"okta.configure:*/*">>, 9 | <<"okta.tag:administrator">> 10 | ], 11 | 12 | <<"monitoring">> => [ 13 | <<"okta.read:*/*">>, 14 | <<"okta.tag:management">> 15 | ] 16 | 17 | 18 | }} 19 | ]} % rabbitmq_auth_backend_oauth2 20 | ]. 21 | -------------------------------------------------------------------------------- /conf/okta/rabbitmq.conf.tmpl: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | management.oauth_enabled = true 4 | management.oauth_client_id = {okta_client_app_ID} 5 | management.oauth_scopes = admin monitoring 6 | management.oauth_metadata_url = {okta-domain-name}/oauth2/default/.well-known/oauth-authorization-server 7 | management.oauth_provider_url = {okta-domain-name}/oauth2/default 8 | 9 | auth_oauth2.resource_server_id = {okta_client_app_ID} 10 | auth_oauth2.jwks_url = {okta-domain-name}/oauth2/default/v1/keys 11 | auth_oauth2.additional_scopes_key = role 12 | auth_oauth2.verify_aud = false 13 | auth_oauth2.scope_prefix = okta. 14 | auth_oauth2.https.hostname_verification = wildcard 15 | -------------------------------------------------------------------------------- /conf/okta/requires-tls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitmq/rabbitmq-oauth2-tutorial/e1b959370ab7b626a0cb7635957be8ea623a3bac/conf/okta/requires-tls -------------------------------------------------------------------------------- /conf/okta/tls.conf: -------------------------------------------------------------------------------- 1 | management.ssl.port = 15671 2 | management.ssl.cacertfile = /certs/ca_rabbitmq_certificate.pem 3 | management.ssl.certfile = /certs/server_rabbitmq_certificate.pem 4 | management.ssl.keyfile = /certs/server_rabbitmq_key.pem 5 | management.ssl.fail_if_no_peer_cert = false 6 | management.ssl.client_renegotiation = false 7 | management.ssl.secure_renegotiate = true 8 | management.ssl.honor_ecc_order = true 9 | management.ssl.honor_cipher_order = true -------------------------------------------------------------------------------- /conf/portal/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | FROM atools/jdk-maven-node:mvn3-jdk11-node16 as base 3 | 4 | WORKDIR /code 5 | 6 | COPY package.json package.json 7 | 8 | FROM base as test 9 | RUN npm install 10 | 11 | ENTRYPOINT [ "npm" ] 12 | CMD [ "" ] 13 | -------------------------------------------------------------------------------- /conf/portal/app.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const app = express(); 3 | const fs = require('fs'); 4 | const https = require('https'); 5 | var path = require('path'); 6 | const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest 7 | 8 | const rabbitmq_url = process.env.RABBITMQ_URL; 9 | const proxied_rabbitmq_url = process.env.PROXIED_RABBITMQ_URL; 10 | const client_id = process.env.CLIENT_ID; 11 | const client_secret = process.env.CLIENT_SECRET; 12 | const uaa_url = process.env.UAA_URL; 13 | const port = process.env.PORT || 3000; 14 | 15 | app.engine('.html', require('ejs').__express); 16 | app.set('views', path.join(__dirname, 'views')); 17 | app.set('view engine', 'html'); 18 | 19 | app.get('/', function(req, res){ 20 | let id = default_if_blank(req.query.client_id, client_id) 21 | let secret = default_if_blank(req.query.client_secret, client_secret) 22 | if (id == 'undefined' || secret == 'undefined') { 23 | res.render('unauthenticated') 24 | }else { 25 | res.render('rabbitmq', { 26 | proxied_url: proxied_rabbitmq_url, 27 | url: rabbitmq_url.replace(/\/?$/, '/') + "login", 28 | name: rabbitmq_url + " for " + id, 29 | access_token: access_token(id, secret) 30 | }) 31 | } 32 | }) 33 | 34 | app.get('/favicon.ico', (req, res) => res.status(204)); 35 | 36 | app.get('/logout', function(req, res) { 37 | const redirectUrl = uaa_url + '/logout.do?client_id=' + client_id + "&redirect=https://portal:3000" 38 | console.debug("Received /logout request -> redirect to " + redirectUrl) 39 | res.redirect(redirectUrl); 40 | }) 41 | 42 | https 43 | .createServer( 44 | { 45 | cert: fs.readFileSync('/etc/portal/server_portal_certificate.pem'), 46 | key: fs.readFileSync('/etc/portal/server_portal_key.pem') 47 | }, 48 | app 49 | ) 50 | .listen(port) 51 | 52 | console.log('Express started on port ' + port); 53 | 54 | function default_if_blank(value, defaultValue) { 55 | if (typeof value === "undefined" || value === null || value == "") { 56 | return defaultValue; 57 | } else { 58 | return value; 59 | } 60 | } 61 | 62 | function access_token(id, secret) { 63 | const req = new XMLHttpRequest(); 64 | const url = uaa_url + '/oauth/token'; 65 | const params = 'client_id=' + id + 66 | '&client_secret=' + secret + 67 | '&grant_type=client_credentials' + 68 | '&token_format=jwt' + 69 | '&response_type=token'; 70 | 71 | console.debug("Sending " + url + " with params "+ params); 72 | 73 | req.open('POST', url, false); 74 | req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 75 | req.setRequestHeader('Accept', 'application/json'); 76 | req.send(params); 77 | if (req.status == 200) { 78 | const token = JSON.parse(req.responseText).access_token; 79 | console.log("Token => " + token) 80 | return token 81 | } else { 82 | throw new Error(req.status + " : " + " : " + 83 | req.response + " : " + req.responseText) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /conf/portal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "selenium", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "portal": "node portal/app.js", 8 | "proxy": "node portal/proxy.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "chromedriver": "^132.0", 15 | "ejs": "^3.1.8", 16 | "express": "^4.18.2", 17 | "geckodriver": "^3.0.2", 18 | "http-proxy": "^1.18.1", 19 | "mqtt": "^5.3.3", 20 | "path": "^0.12.7", 21 | "proxy": "^1.0.2", 22 | "rhea": "^3.0.3", 23 | "selenium-webdriver": "^4.26.0", 24 | "xmlhttprequest": "^1.8.0" 25 | }, 26 | "devDependencies": { 27 | "chai": "^4.3.6", 28 | "mocha": "^10.4.0", 29 | "request": "^2.88.2", 30 | "standard": "^17.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /conf/portal/proxy.js: -------------------------------------------------------------------------------- 1 | var http = require('http'), 2 | httpProxy = require('http-proxy'), 3 | fs = require('fs'); 4 | const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest 5 | 6 | const rabbitmq_url = process.env.RABBITMQ_URL || 'http://0.0.0.0:15672/'; 7 | const client_id = process.env.CLIENT_ID; 8 | const client_secret = process.env.CLIENT_SECRET; 9 | const uaa_url = process.env.UAA_URL; 10 | const port = process.env.PORT; 11 | 12 | // 13 | // Create a proxy server with custom application logic 14 | // 15 | var proxy = httpProxy.createProxyServer({}); 16 | 17 | proxy.on('proxyReq', function(proxyReq, req, res, options) { 18 | console.log("proxing " + req.url) 19 | if (req.url.endsWith("bootstrap.js")) { 20 | proxyReq.setHeader('Authorization', 'Bearer ' + access_token(client_id, client_secret)); 21 | } 22 | proxyReq.setHeader('origin', req.url) 23 | proxyReq.setHeader('Access-Control-Allow-Origin', '*'); 24 | proxyReq.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS'); 25 | 26 | }); 27 | var server = http.createServer({ 28 | ssl: { 29 | key: fs.readFileSync('/etc/proxy/server_proxy_key.pem', 'utf8'), 30 | cert: fs.readFileSync('/etc/proxy/server_proxy_certificate.pem', 'utf8') 31 | }, 32 | target: 'https://rabbitmq:15671', 33 | secure: true 34 | }); 35 | console.log("Proxy listening on port " + port + ". RABBITMQ_URL=" + rabbitmq_url) 36 | server.listen(port); 37 | 38 | 39 | function default_if_blank(value, defaultValue) { 40 | if (typeof value === "undefined" || value === null || value == "") { 41 | return defaultValue; 42 | } else { 43 | return value; 44 | } 45 | } 46 | 47 | function access_token(id, secret) { 48 | const req = new XMLHttpRequest(); 49 | const url = uaa_url + '/oauth/token'; 50 | const params = 'client_id=' + id + 51 | '&client_secret=' + secret + 52 | '&grant_type=client_credentials' + 53 | '&token_format=jwt' + 54 | '&response_type=token'; 55 | 56 | console.debug("Sending " + url + " with params "+ params); 57 | 58 | req.open('POST', url, false); 59 | req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 60 | req.setRequestHeader('Accept', 'application/json'); 61 | req.send(params); 62 | console.log("Ret " + req.status) 63 | if (req.status == 200) { 64 | const token = JSON.parse(req.responseText).access_token; 65 | console.log("Token => " + token) 66 | return token; 67 | } else { 68 | throw new Error(req.status + " : " + req.responseText); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /conf/portal/rabbitmq.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | log.console.level = debug 4 | 5 | management.oauth_enabled = true 6 | management.oauth_client_id = rabbitmq-client-code 7 | management.oauth_scopes = openid profile rabbitmq.tag:administrator 8 | management.oauth_initiated_logon_type = idp_initiated 9 | management.oauth_provider_url = https://localhost:3000 10 | 11 | auth_oauth2.resource_server_id = rabbitmq 12 | auth_oauth2.preferred_username_claims.1 = user_name 13 | auth_oauth2.additional_scopes_key = extra_scope 14 | auth_oauth2.issuer = https://uaa:8443 15 | auth_oauth2.https.cacertfile = /etc/uaa/certs/ca_uaa_certificate.pem 16 | -------------------------------------------------------------------------------- /conf/portal/requires-tls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitmq/rabbitmq-oauth2-tutorial/e1b959370ab7b626a0cb7635957be8ea623a3bac/conf/portal/requires-tls -------------------------------------------------------------------------------- /conf/portal/tls.conf: -------------------------------------------------------------------------------- 1 | management.ssl.port = 15671 2 | management.ssl.cacertfile = /certs/ca_rabbitmq_certificate.pem 3 | management.ssl.certfile = /certs/server_rabbitmq_certificate.pem 4 | management.ssl.keyfile = /certs/server_rabbitmq_key.pem 5 | management.ssl.fail_if_no_peer_cert = false 6 | management.ssl.client_renegotiation = false 7 | management.ssl.secure_renegotiate = true 8 | management.ssl.honor_ecc_order = true 9 | management.ssl.honor_cipher_order = true -------------------------------------------------------------------------------- /conf/portal/views/rabbitmq.html: -------------------------------------------------------------------------------- 1 |

Portal

2 | 3 |

This is a portal used to test Identity-Provider-based authentication. 4 | This means users comes to RabbitMQ with a token already obtained without involving RabbitMQ 5 | management ui. 6 |

7 | 8 |

POST access_token to /login endpoint

9 | This mechanism is available for those portals which cannot inject the access token into the Authorization header. 10 | Instead they submit the access token via the form field access_token to the RabbitMQ /login endpoint. 11 |

12 |
13 | 14 | 15 |
16 | -------------------------------------------------------------------------------- /conf/portal/views/unauthenticated.html: -------------------------------------------------------------------------------- 1 |

FakePortal

2 | 3 |

This is a portal used to test Identity-Provider-based authentication. 4 | This means users comes to RabbitMQ with a token already obtained without involving RabbitMQ 5 | management ui. 6 |

7 | 8 |

This is the state of the Portal when the user is not authenticated yet.

9 |

To get the fakeportal fully authenticated, pass two request parameters: 10 |

    11 |
  • client_id
  • 12 |
  • client_secret
  • 13 |
14 | These credentitals are used to get an access token from UAA and send it to 15 | RabbitMQ. 16 |

17 | 18 | 19 | -------------------------------------------------------------------------------- /conf/private-2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpQIBAAKCAQEAphWvkBVP81vRCV+x/3KaosUQOXs8XrSS+f5uincwssmDV/6g 3 | PX7R2QoEKsYXBgW1/xEGT6Ax/awx1g+lOAk6l2dWJpAifJslrbWQLwMngqddw0tU 4 | tbzTwtkeWGMO0y5IL1FiM/KYBKd4ugQ7GnVcCefTqr+l4wkPeCfLzwKuexCxNICx 5 | WyO2bkHF6CZh7Wsa1nEItxaCUYuyyvuoy8FxazcqdP8LW93Z3tffUNUaIPab5uww 6 | SWcv4ELYeDNZDLTF17Fi/Wn6d0iy4OLCTAutBcvhScEn68QIAaAkSpv5ObtZEHST 7 | 2qZEiXBva1pba4+oYX3MyZy52lfRc+/30CONAQIDAQABAoIBAQCcVelunUEm+JSq 8 | WDP7GuvIr+r30LMhCqUXQZLYMB3dDabfG8XGXSw3OyB1CwX9Gz8Xm/Tu2wJzoLVA 9 | pHWHa9iFUDZeEmsEFB7Bhxjzx+pXKCgwfyZ79AT5ctsHpCb+TqCQOfFQqNjD+MjB 10 | gN4Jp9M9V8V9Au2p6otvNTa54/JN0AI6vPTh08Y5ZtUczGiTN6WwxgozNJlMChxz 11 | rDZbaeJ4m/ooLMQL97YX9tPQH6td9Mob1Rp2WLmNq/S3LD7/ZwQnBjqv/nsD2nbe 12 | UpaxeDzD7j9v3nIKEOMYRVhsjuYNyLcc4+OfGYHuZMrrK2He5oqtTlxIkxDAtgpi 13 | /CQCBCIJAoGBANTSU6jbKFTPIeR5GrXWe6CDG9hr6O2iNFwxUugMW2gldBMZC+Cz 14 | uSEQGLbYhs5Q0TtEBelf8qFyguhmROnIBS3gLV31k5dSTQCL75IsfKBPU40oyoF/ 15 | 2NIRGa6kMOBOxScF0Q6rth9o01MR5C4S9poSbJk1EL9OBNPKYS9phGnLAoGBAMfH 16 | 6DK9z5v2bnmutqmTjW5sFUtpVdkjFt2AkR2azge8K4m+PN2mgmpYSqIWeQY/aMco 17 | glc7LRj4vpu1Z2RKGOAbQqUrdE6ihkeawGP0LFEs1603PW/7jBOIdqeBhXRGzSzh 18 | gICUz32ChUkZ0cAMSBytEFCstaMSWbveER+SDXrjAoGBAM2YotltXvkPYV6m3/bq 19 | zWOzRSM+nDd1i7/EpqMlzOg/xnLsr1zUQvR96GI7q3+E85ydilh6KJtvVKfOpKR0 20 | Zwx6lVk/9OUqzNjKVxaPg5YbDExCK+AO8hd+DaF5XP5VGoEoTV4u5DJTwlNt5VHd 21 | X/5X7jHT4enuJRu1V03GUfUhAoGAAIiRHymQl1sGGn8T78n8E7JoMCZc21KTqg3A 22 | 1XJnYG/pMdn3MaRTLtODh4FF23Vp4zZBetgmm612XNYUK5ljDZ4lBGnkSp12fFR2 23 | dQ3e3GyhOs4t9NGYIyk3H+VhpNjXjWogvLcpAq3Ji1NtUvT1cFYp9/0uEvxmjvDd 24 | 3Na4AH8CgYEAswiMR7DY/h4X3OJsoepGXnFIMsydy6udB2Ccn2BB39w6oFuhVlGW 25 | UcvfcgTWE9QHJm4J/QFnECIBXanZVxytFJhq2dhnJrc0y3zagrtmmYmd901jgXnQ 26 | 3Oj0hVpg3SWNZG5j3K0r364R5JMupVMtH4YOUbdnnGn2GX4IUQRpHho= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /conf/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEA2dP+vRn+Kj+S/oGd49kq6+CKNAduCC1raLfTH7B3qjmZYm45 3 | yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhKIdcIWadhqDzdtn1hj/22iUwrhH0b 4 | d475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2B9q9KFBmo4Ahh/6+d4wM1rH9kxl0 5 | RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF2cr3wQwCfF1qVu4eAVNVfxfy/uEv 6 | G3Q7x005P3TcK+QcYgJxav3lictSi5dyWLgGQAvkknWitpRK8KVLypEj5WKej6CF 7 | 8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7VwIDAQABAoIBAFsB5FszYepa11o3 8 | 4zSPxgv4qyUjuYf3GfoNW0rRGp3nJLtoHAIYa0CcLX9kzsQfmLtxoY46mdppxr8Z 9 | 2qUZpBdRVO7ILNfyXhthdQKI2NuyFDhtYK1p8bx6BXe095HMcvm2ohjXzPdTP4Hq 10 | HrXAYXjUndUbClbjMJ82AnPF8pM70kBq7g733UqkdfrMuv6/d95Jiyw4cC7dGsI3 11 | Ruz9DGhiAyCBtQ0tUB+6Kqn5DChSB+ccfMJjr6GnCVYmERxEQ5DJCTIX8am8C6KX 12 | mAxUwHMTsEGBU6GzhcUgAwUFEK3I9RptdlRFp7F8E/P0LxmPkFdgaBNUhrdnB7Y4 13 | 01n1R1kCgYEA/huFJgwVWSBSK/XIouFuQrxZOI9JbBbdmpFT7SBGCdFg26Or9y7j 14 | +N5HE7yuoZ9PkBh17zzosZdsJhGocRYvO0LSq8cXvKXKCwn2fTMM7uJ/oQe68sxG 15 | cF/fC0M/8LvRESWShH920rrERu0s161RuasdOPre0aXu7ZQzkQ68O6MCgYEA23NO 16 | DHKNblBOdFEWsvotLqV8DrIbQ4le7sSgQr56/bdn9GScZk2JU0f+pqzpiGUy9bIt 17 | 6uujvt5ar0IvpIQVdjf3dbp6Fy+Dwhd4yTR4dMdDECest7jL++/21x8Y0ywFhBIK 18 | yEd+QxpOLXP6qaSKTGxL2rnTXRjl8/g629xQPL0CgYEAkNNOh+jLIgjxzGxA9dRV 19 | 62M91qaTyi8eDkJV+wgx4taaxZP7Jt5qwCSvjegz/5m01wOZ88hbNxx+XxQhVJK4 20 | SKZFO/I07Sfwh2oeOi0maeBdrYGiY09ZtiJuFRU3FBV3irZHU4zyRBh+VY5HyITX 21 | 12JXPWp+JC7WhkG5QiuLzNECgYEA15OBzICLpx6Es4clAVT6JaSzJcyZM9MyyuOl 22 | e2ubbrpJCK/9ZBIvIPzMj/e0wiSH1wzeRrSM+ud7tkcSfk6ytptsIN67KSOoD3b3 23 | VNCStEU7ABe5eBG1cRzeI52MyYWpNYBzzyNMSacBvWz9hMD6ivCn44pAtGfNHclw 24 | KKNYvxECgYBOamf25md9Jy6rtQsJVEJWw+8sB4lBlKEEadc5qekR7ZQ0hwj8CnTm 25 | WOo856ynI28Sog62iw8F/do/z0B29RuGuxw+prkBkn3lg/VQXEitzqcYvota6osa 26 | 8XSfaPiTyQwWpzbFNZzzemlTsIDiF3UqwkHvWaMYPDf4Ng3cokPPxw== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /conf/public-2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAphWvkBVP81vRCV+x/3Ka 3 | osUQOXs8XrSS+f5uincwssmDV/6gPX7R2QoEKsYXBgW1/xEGT6Ax/awx1g+lOAk6 4 | l2dWJpAifJslrbWQLwMngqddw0tUtbzTwtkeWGMO0y5IL1FiM/KYBKd4ugQ7GnVc 5 | CefTqr+l4wkPeCfLzwKuexCxNICxWyO2bkHF6CZh7Wsa1nEItxaCUYuyyvuoy8Fx 6 | azcqdP8LW93Z3tffUNUaIPab5uwwSWcv4ELYeDNZDLTF17Fi/Wn6d0iy4OLCTAut 7 | BcvhScEn68QIAaAkSpv5ObtZEHST2qZEiXBva1pba4+oYX3MyZy52lfRc+/30CON 8 | AQIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /conf/public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2dP+vRn+Kj+S/oGd49kq 3 | 6+CKNAduCC1raLfTH7B3qjmZYm45yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhK 4 | IdcIWadhqDzdtn1hj/22iUwrhH0bd475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2 5 | B9q9KFBmo4Ahh/6+d4wM1rH9kxl0RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF 6 | 2cr3wQwCfF1qVu4eAVNVfxfy/uEvG3Q7x005P3TcK+QcYgJxav3lictSi5dyWLgG 7 | QAvkknWitpRK8KVLypEj5WKej6CF8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7 8 | VwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /conf/uaa-symmetrical/advanced.config: -------------------------------------------------------------------------------- 1 | [ 2 | %% Set a resource server ID. Will require all scopes to be prefixed with `rabbitmq.` 3 | {rabbitmq_auth_backend_oauth2, [ 4 | % Set up a legacy signing key 5 | {key_config, [ 6 | {signing_keys, #{ 7 | <<"legacy-token-key">> => 8 | {map, #{ 9 | <<"alg">> => <<"HS256">>, 10 | <<"value">> => <<"legacy-token-key">>, 11 | <<"kty">> => <<"MAC">>, 12 | <<"use">> => <<"sig">>} 13 | } 14 | } 15 | } %% signing keys 16 | ]} % key_config 17 | ]} % rabbitmq_auth_backend_oauth2 18 | ]. 19 | -------------------------------------------------------------------------------- /conf/uaa-symmetrical/log4j2.properties: -------------------------------------------------------------------------------- 1 | status = error 2 | dest = err 3 | name = UaaLog 4 | 5 | property.log_pattern=[%d{yyyy-MM-dd'T'HH:mm:ss.nnnnnn}{GMT+0}Z] uaa%X{context} - %pid [%t] .... %5p --- %c{1}: %replace{%m}{(?<=password=|client_secret=)([^&]*)}{}%n 6 | 7 | appender.uaaDefaultAppender.type = File 8 | appender.uaaDefaultAppender.name = UaaDefaultAppender 9 | appender.uaaDefaultAppender.fileName = logs/uaa.log 10 | appender.uaaDefaultAppender.layout.type = PatternLayout 11 | appender.uaaDefaultAppender.layout.pattern = ${log_pattern} 12 | 13 | appender.uaaAuditAppender.type = File 14 | appender.uaaAuditAppender.name = UaaAuditAppender 15 | appender.uaaAuditAppender.fileName = logs/uaa_events.log 16 | appender.uaaAuditAppender.layout.type = PatternLayout 17 | appender.uaaAuditAppender.layout.pattern = ${log_pattern} 18 | 19 | rootLogger.level = debug 20 | rootLogger.appenderRef.uaaDefaultAppender.ref = UaaDefaultAppender 21 | 22 | logger.UAAAudit.name = UAA.Audit 23 | logger.UAAAudit.level = info 24 | logger.UAAAudit.additivity = true 25 | logger.UAAAudit.appenderRef.auditEventLog.ref = UaaAuditAppender 26 | 27 | logger.cfIdentity.name = org.cloudfoundry.identity 28 | logger.cfIdentity.level = info 29 | logger.cfIdentity.additivity = false 30 | logger.cfIdentity.appenderRef.uaaDefaultAppender.ref = UaaDefaultAppender 31 | -------------------------------------------------------------------------------- /conf/uaa-symmetrical/rabbitmq.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | 3 | management.oauth_enabled = true 4 | auth_oauth2.resource_server_id = rabbitmq 5 | auth_oauth2.default_key = legacy-token-key 6 | -------------------------------------------------------------------------------- /conf/uaa-symmetrical/uaa.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | config: /uaa/log4j2.properties 3 | 4 | issuer: 5 | uri: http://local:8080/ 6 | 7 | encryption: 8 | active_key_label: CHANGE-THIS-KEY 9 | encryption_keys: 10 | - label: CHANGE-THIS-KEY 11 | passphrase: CHANGEME 12 | 13 | logout: 14 | redirect: 15 | parameter: 16 | disable: false 17 | whitelist: 18 | http://localhost:15672/* 19 | 20 | login: 21 | serviceProviderKey: | 22 | -----BEGIN RSA PRIVATE KEY----- 23 | MIICXQIBAAKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5 24 | L39WqS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vA 25 | fpOwznoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQAB 26 | AoGAVOj2Yvuigi6wJD99AO2fgF64sYCm/BKkX3dFEw0vxTPIh58kiRP554Xt5ges 27 | 7ZCqL9QpqrChUikO4kJ+nB8Uq2AvaZHbpCEUmbip06IlgdA440o0r0CPo1mgNxGu 28 | lhiWRN43Lruzfh9qKPhleg2dvyFGQxy5Gk6KW/t8IS4x4r0CQQD/dceBA+Ndj3Xp 29 | ubHfxqNz4GTOxndc/AXAowPGpge2zpgIc7f50t8OHhG6XhsfJ0wyQEEvodDhZPYX 30 | kKBnXNHzAkEAyCA76vAwuxqAd3MObhiebniAU3SnPf2u4fdL1EOm92dyFs1JxyyL 31 | gu/DsjPjx6tRtn4YAalxCzmAMXFSb1qHfwJBAM3qx3z0gGKbUEWtPHcP7BNsrnWK 32 | vw6By7VC8bk/ffpaP2yYspS66Le9fzbFwoDzMVVUO/dELVZyBnhqSRHoXQcCQQCe 33 | A2WL8S5o7Vn19rC0GVgu3ZJlUrwiZEVLQdlrticFPXaFrn3Md82ICww3jmURaKHS 34 | N+l4lnMda79eSp3OMmq9AkA0p79BvYsLshUJJnvbk76pCjR28PK4dV1gSDUEqQMB 35 | qy45ptdwJLqLJCeNoR0JUcDNIRhOCuOPND7pcMtX6hI/ 36 | -----END RSA PRIVATE KEY----- 37 | serviceProviderKeyPassword: password 38 | serviceProviderCertificate: | 39 | -----BEGIN CERTIFICATE----- 40 | MIIDSTCCArKgAwIBAgIBADANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJhdzEO 41 | MAwGA1UECBMFYXJ1YmExDjAMBgNVBAoTBWFydWJhMQ4wDAYDVQQHEwVhcnViYTEO 42 | MAwGA1UECxMFYXJ1YmExDjAMBgNVBAMTBWFydWJhMR0wGwYJKoZIhvcNAQkBFg5h 43 | cnViYUBhcnViYS5hcjAeFw0xNTExMjAyMjI2MjdaFw0xNjExMTkyMjI2MjdaMHwx 44 | CzAJBgNVBAYTAmF3MQ4wDAYDVQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAM 45 | BgNVBAcTBWFydWJhMQ4wDAYDVQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAb 46 | BgkqhkiG9w0BCQEWDmFydWJhQGFydWJhLmFyMIGfMA0GCSqGSIb3DQEBAQUAA4GN 47 | ADCBiQKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5L39W 48 | qS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vAfpOw 49 | znoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQABo4Ha 50 | MIHXMB0GA1UdDgQWBBTx0lDzjH/iOBnOSQaSEWQLx1syGDCBpwYDVR0jBIGfMIGc 51 | gBTx0lDzjH/iOBnOSQaSEWQLx1syGKGBgKR+MHwxCzAJBgNVBAYTAmF3MQ4wDAYD 52 | VQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAMBgNVBAcTBWFydWJhMQ4wDAYD 53 | VQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAbBgkqhkiG9w0BCQEWDmFydWJh 54 | QGFydWJhLmFyggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYvBJ 55 | 0HOZbbHClXmGUjGs+GS+xC1FO/am2suCSYqNB9dyMXfOWiJ1+TLJk+o/YZt8vuxC 56 | KdcZYgl4l/L6PxJ982SRhc83ZW2dkAZI4M0/Ud3oePe84k8jm3A7EvH5wi5hvCkK 57 | RpuRBwn3Ei+jCRouxTbzKPsuCVB+1sNyxMTXzf0= 58 | -----END CERTIFICATE----- 59 | #The secret that an external login server will use to authenticate to the uaa using the id `login` 60 | LOGIN_SECRET: loginsecret 61 | 62 | jwt: 63 | token: 64 | policy: 65 | # Will override global validity policies for the default zone only. 66 | #accessTokenValiditySeconds: 600 67 | keys: 68 | legacy-token-key: 69 | signingKey: legacy-token-key 70 | verificationKey: legacy-token-key 71 | 72 | scim: 73 | users: 74 | - rabbit_admin|rabbit_admin|scim.read,openid,rabbitmq.read:*/*,rabbitmq.write:*/*,rabbitmq.configure:*/*,rabbitmq.tag:administrator 75 | - rabbitmq_management|rabbitmq_management|scim.read,openid,rabbitmq.read:*/*,rabbitmq.write:*/*,rabbitmq.configure:*/*,rabbitmq.tag:management 76 | - rabbit_monitor|rabbit_monitor|scim.read,openid,rabbitmq.tag:monitoring 77 | groups: 78 | 'rabbitmq.read:*/*': Read all 79 | 'rabbitmq.write:*/*': Write all 80 | 'rabbitmq.configure:*/*': Configure all 81 | 'rabbitmq.tag:management': Management 82 | 'rabbitmq.tag:monitoring': Monitoring 83 | 'rabbitmq.tag:administrator': Administrator 84 | 85 | oauth: 86 | # Always override clients on startup 87 | client: 88 | override: true 89 | 90 | # List of OAuth clients 91 | clients: 92 | admin: 93 | id: admin 94 | secret: adminsecret 95 | authorized-grant-types: client_credentials 96 | scope: none 97 | authorities: uaa.admin,clients.admin,clients.read,clients.write,clients.secret,scim.write,scim.read,uaa.resource 98 | mgt_api_client: 99 | id: mgt_api_client 100 | secret: mgt_api_client 101 | authorized-grant-types: client_credentials 102 | authorities: rabbitmq.tag:monitoring 103 | rabbit_client_code: 104 | id: rabbit_client_code 105 | secret: rabbit_client_code 106 | authorized-grant-types: authorization_code 107 | scope: rabbitmq.*,openid,profile 108 | authorities: uaa.resource,rabbitmq 109 | redirect-uri: http://localhost:15672 110 | allowpublic: true 111 | mgt_api_client_2: 112 | id: mgt_api_client_2 113 | secret: mgt_api_client_2 114 | authorized-grant-types: client_credentials 115 | authorities: api://rabbitmq:management 116 | producer: 117 | id: producer 118 | secret: producer_secret 119 | authorities: rabbitmq.write:*/*,rabbitmq.read:*/*,rabbitmq.configure:*/* 120 | authorized-grant-types: client_credentials 121 | consumer: 122 | id: consumer 123 | secret: consumer_secret 124 | authorities: rabbitmq.read:*/* rabbitmq.configure:*/* rabbitmq.write:*/x-* rabbitmq.write:*/q-* 125 | authorized-grant-types: client_credentials 126 | jms_producer: 127 | id: jms_producer 128 | secret: jms_producer_secret 129 | authorities: rabbitmq.write:%2F/*,rabbitmq.read:%2F/*,rabbitmq.configure:%2F/*,rabbitmq.configure:*/jms.durable.queues,rabbitmq.write:*/jms.durable.queues,rabbitmq.read:*/jms.durable.queues 130 | authorized-grant-types: client_credentials 131 | jms_consumer: 132 | id: jms_consumer 133 | secret: jms_consumer_secret 134 | authorities: rabbitmq.read:*/* rabbitmq.configure:*/* rabbitmq.write:*/x-* rabbitmq.write:*/q-* rabbitmq.write:*/jms.durable.queues 135 | authorized-grant-types: client_credentials 136 | producer_with_roles: 137 | id: producer_with_roles 138 | secret: producer_with_roles_secret 139 | authorities: rabbitmq.*,api://rabbitmq:producer,api://rabbitmq:Administrator 140 | authorized-grant-types: client_credentials 141 | consumer_with_roles: 142 | id: consumer_with_roles 143 | secret: consumer_with_roles_secret 144 | authorities: rabbitmq.* api://rabbitmq:Read.All api://rabbitmq:Configure.All api://rabbitmq:Write.All 145 | authorized-grant-types: client_credentials 146 | -------------------------------------------------------------------------------- /conf/uaa/advanced-scope-aliases.config: -------------------------------------------------------------------------------- 1 | [ 2 | {rabbitmq_auth_backend_oauth2, [ 3 | {scope_aliases, #{ 4 | <<"api://rabbitmq:Read.All">> => [<<"rabbitmq.read:*/*">>], 5 | <<"api://rabbitmq:Write.All">> => [<<"rabbitmq.write:*/*">>], 6 | <<"api://rabbitmq:Configure.All">> => [<<"rabbitmq.configure:*/*">>], 7 | <<"api://rabbitmq:Administrator">> => [<<"rabbitmq.tag:administrator">>], 8 | <<"api://rabbitmq:producer">> => [ 9 | <<"rabbitmq.read:*/*">>, 10 | <<"rabbitmq.write:*/*">>, 11 | <<"rabbitmq.configure:*/*">>, 12 | <<"rabbitmq.tag:management">> 13 | ] 14 | }} 15 | ]} 16 | ]. 17 | -------------------------------------------------------------------------------- /conf/uaa/authn-and-authz.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1.authn = rabbit_auth_backend_oauth2 2 | auth_backends.1.authz = internal -------------------------------------------------------------------------------- /conf/uaa/log4j2.properties: -------------------------------------------------------------------------------- 1 | status = error 2 | dest = err 3 | name = UaaLog 4 | 5 | property.log_pattern=[%d{yyyy-MM-dd'T'HH:mm:ss.nnnnnn}{GMT+0}Z] uaa%X{context} - %pid [%t] .... %5p --- %c{1}: %replace{%m}{(?<=password=|client_secret=)([^&]*)}{}%n 6 | 7 | appender.uaaDefaultAppender.type = File 8 | appender.uaaDefaultAppender.name = UaaDefaultAppender 9 | appender.uaaDefaultAppender.fileName = logs/uaa.log 10 | appender.uaaDefaultAppender.layout.type = PatternLayout 11 | appender.uaaDefaultAppender.layout.pattern = ${log_pattern} 12 | 13 | appender.uaaAuditAppender.type = File 14 | appender.uaaAuditAppender.name = UaaAuditAppender 15 | appender.uaaAuditAppender.fileName = logs/uaa_events.log 16 | appender.uaaAuditAppender.layout.type = PatternLayout 17 | appender.uaaAuditAppender.layout.pattern = ${log_pattern} 18 | 19 | rootLogger.level = debug 20 | rootLogger.appenderRef.uaaDefaultAppender.ref = UaaDefaultAppender 21 | 22 | logger.UAAAudit.name = UAA.Audit 23 | logger.UAAAudit.level = info 24 | logger.UAAAudit.additivity = true 25 | logger.UAAAudit.appenderRef.auditEventLog.ref = UaaAuditAppender 26 | 27 | logger.cfIdentity.name = org.cloudfoundry.identity 28 | logger.cfIdentity.level = info 29 | logger.cfIdentity.additivity = false 30 | logger.cfIdentity.appenderRef.uaaDefaultAppender.ref = UaaDefaultAppender 31 | -------------------------------------------------------------------------------- /conf/uaa/oauth2-and-internal.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 2 | auth_backends.2 = rabbit_auth_backend_internal -------------------------------------------------------------------------------- /conf/uaa/oauth2-only.conf: -------------------------------------------------------------------------------- 1 | auth_backends.1 = rabbit_auth_backend_oauth2 -------------------------------------------------------------------------------- /conf/uaa/rabbitmq.conf: -------------------------------------------------------------------------------- 1 | 2 | log.default.level = debug 3 | 4 | management.oauth_enabled = true 5 | management.oauth_client_id = rabbit_client_code 6 | management.oauth_scopes = openid profile rabbitmq.* 7 | 8 | auth_oauth2.resource_server_id = rabbitmq 9 | auth_oauth2.issuer = https://uaa:8443 10 | auth_oauth2.https.cacertfile = /certs/ca_uaa_certificate.pem 11 | auth_oauth2.additional_scopes_key = extra_scope 12 | auth_oauth2.verify_aud = false 13 | auth_oauth2.preferred_username_claims.1 = preferred_username 14 | auth_oauth2.preferred_username_claims.2 = user_name 15 | auth_oauth2.preferred_username_claims.3 = email 16 | -------------------------------------------------------------------------------- /conf/uaa/rar-tokens.conf: -------------------------------------------------------------------------------- 1 | 2 | auth_oauth2.resource_server_type = rabbitmq 3 | -------------------------------------------------------------------------------- /conf/uaa/server.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 23 | 28 | 29 | 34 | 38 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /conf/uaa/signing-key/signing-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2dP+vRn+Kj+S/oGd49kq 3 | 6+CKNAduCC1raLfTH7B3qjmZYm45yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhK 4 | IdcIWadhqDzdtn1hj/22iUwrhH0bd475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2 5 | B9q9KFBmo4Ahh/6+d4wM1rH9kxl0RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF 6 | 2cr3wQwCfF1qVu4eAVNVfxfy/uEvG3Q7x005P3TcK+QcYgJxav3lictSi5dyWLgG 7 | QAvkknWitpRK8KVLypEj5WKej6CF8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7 8 | VwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /conf/uaa/uaa.yml: -------------------------------------------------------------------------------- 1 | require_https: true 2 | https_port: 8443 3 | 4 | logging: 5 | config: /uaa/log4j2.properties 6 | 7 | issuer: 8 | uri: https://localhost:8443/ 9 | 10 | encryption: 11 | active_key_label: CHANGE-THIS-KEY 12 | encryption_keys: 13 | - label: CHANGE-THIS-KEY 14 | passphrase: CHANGEME 15 | 16 | logout: 17 | redirect: 18 | parameter: 19 | disable: false 20 | whitelist: 21 | http://localhost:15672/* 22 | 23 | login: 24 | serviceProviderKey: | 25 | -----BEGIN RSA PRIVATE KEY----- 26 | MIICXQIBAAKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5 27 | L39WqS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vA 28 | fpOwznoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQAB 29 | AoGAVOj2Yvuigi6wJD99AO2fgF64sYCm/BKkX3dFEw0vxTPIh58kiRP554Xt5ges 30 | 7ZCqL9QpqrChUikO4kJ+nB8Uq2AvaZHbpCEUmbip06IlgdA440o0r0CPo1mgNxGu 31 | lhiWRN43Lruzfh9qKPhleg2dvyFGQxy5Gk6KW/t8IS4x4r0CQQD/dceBA+Ndj3Xp 32 | ubHfxqNz4GTOxndc/AXAowPGpge2zpgIc7f50t8OHhG6XhsfJ0wyQEEvodDhZPYX 33 | kKBnXNHzAkEAyCA76vAwuxqAd3MObhiebniAU3SnPf2u4fdL1EOm92dyFs1JxyyL 34 | gu/DsjPjx6tRtn4YAalxCzmAMXFSb1qHfwJBAM3qx3z0gGKbUEWtPHcP7BNsrnWK 35 | vw6By7VC8bk/ffpaP2yYspS66Le9fzbFwoDzMVVUO/dELVZyBnhqSRHoXQcCQQCe 36 | A2WL8S5o7Vn19rC0GVgu3ZJlUrwiZEVLQdlrticFPXaFrn3Md82ICww3jmURaKHS 37 | N+l4lnMda79eSp3OMmq9AkA0p79BvYsLshUJJnvbk76pCjR28PK4dV1gSDUEqQMB 38 | qy45ptdwJLqLJCeNoR0JUcDNIRhOCuOPND7pcMtX6hI/ 39 | -----END RSA PRIVATE KEY----- 40 | serviceProviderKeyPassword: password 41 | serviceProviderCertificate: | 42 | -----BEGIN CERTIFICATE----- 43 | MIIDSTCCArKgAwIBAgIBADANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJhdzEO 44 | MAwGA1UECBMFYXJ1YmExDjAMBgNVBAoTBWFydWJhMQ4wDAYDVQQHEwVhcnViYTEO 45 | MAwGA1UECxMFYXJ1YmExDjAMBgNVBAMTBWFydWJhMR0wGwYJKoZIhvcNAQkBFg5h 46 | cnViYUBhcnViYS5hcjAeFw0xNTExMjAyMjI2MjdaFw0xNjExMTkyMjI2MjdaMHwx 47 | CzAJBgNVBAYTAmF3MQ4wDAYDVQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAM 48 | BgNVBAcTBWFydWJhMQ4wDAYDVQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAb 49 | BgkqhkiG9w0BCQEWDmFydWJhQGFydWJhLmFyMIGfMA0GCSqGSIb3DQEBAQUAA4GN 50 | ADCBiQKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5L39W 51 | qS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vAfpOw 52 | znoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQABo4Ha 53 | MIHXMB0GA1UdDgQWBBTx0lDzjH/iOBnOSQaSEWQLx1syGDCBpwYDVR0jBIGfMIGc 54 | gBTx0lDzjH/iOBnOSQaSEWQLx1syGKGBgKR+MHwxCzAJBgNVBAYTAmF3MQ4wDAYD 55 | VQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAMBgNVBAcTBWFydWJhMQ4wDAYD 56 | VQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAbBgkqhkiG9w0BCQEWDmFydWJh 57 | QGFydWJhLmFyggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYvBJ 58 | 0HOZbbHClXmGUjGs+GS+xC1FO/am2suCSYqNB9dyMXfOWiJ1+TLJk+o/YZt8vuxC 59 | KdcZYgl4l/L6PxJ982SRhc83ZW2dkAZI4M0/Ud3oePe84k8jm3A7EvH5wi5hvCkK 60 | RpuRBwn3Ei+jCRouxTbzKPsuCVB+1sNyxMTXzf0= 61 | -----END CERTIFICATE----- 62 | #The secret that an external login server will use to authenticate to the uaa using the id `login` 63 | LOGIN_SECRET: loginsecret 64 | 65 | jwt: 66 | token: 67 | policy: 68 | # Will override global validity policies for the default zone only. 69 | #accessTokenValiditySeconds: 600 70 | keys: 71 | legacy-token-key: 72 | signingKey: | 73 | -----BEGIN RSA PRIVATE KEY----- 74 | MIIEpAIBAAKCAQEA2dP+vRn+Kj+S/oGd49kq6+CKNAduCC1raLfTH7B3qjmZYm45 75 | yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhKIdcIWadhqDzdtn1hj/22iUwrhH0b 76 | d475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2B9q9KFBmo4Ahh/6+d4wM1rH9kxl0 77 | RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF2cr3wQwCfF1qVu4eAVNVfxfy/uEv 78 | G3Q7x005P3TcK+QcYgJxav3lictSi5dyWLgGQAvkknWitpRK8KVLypEj5WKej6CF 79 | 8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7VwIDAQABAoIBAFsB5FszYepa11o3 80 | 4zSPxgv4qyUjuYf3GfoNW0rRGp3nJLtoHAIYa0CcLX9kzsQfmLtxoY46mdppxr8Z 81 | 2qUZpBdRVO7ILNfyXhthdQKI2NuyFDhtYK1p8bx6BXe095HMcvm2ohjXzPdTP4Hq 82 | HrXAYXjUndUbClbjMJ82AnPF8pM70kBq7g733UqkdfrMuv6/d95Jiyw4cC7dGsI3 83 | Ruz9DGhiAyCBtQ0tUB+6Kqn5DChSB+ccfMJjr6GnCVYmERxEQ5DJCTIX8am8C6KX 84 | mAxUwHMTsEGBU6GzhcUgAwUFEK3I9RptdlRFp7F8E/P0LxmPkFdgaBNUhrdnB7Y4 85 | 01n1R1kCgYEA/huFJgwVWSBSK/XIouFuQrxZOI9JbBbdmpFT7SBGCdFg26Or9y7j 86 | +N5HE7yuoZ9PkBh17zzosZdsJhGocRYvO0LSq8cXvKXKCwn2fTMM7uJ/oQe68sxG 87 | cF/fC0M/8LvRESWShH920rrERu0s161RuasdOPre0aXu7ZQzkQ68O6MCgYEA23NO 88 | DHKNblBOdFEWsvotLqV8DrIbQ4le7sSgQr56/bdn9GScZk2JU0f+pqzpiGUy9bIt 89 | 6uujvt5ar0IvpIQVdjf3dbp6Fy+Dwhd4yTR4dMdDECest7jL++/21x8Y0ywFhBIK 90 | yEd+QxpOLXP6qaSKTGxL2rnTXRjl8/g629xQPL0CgYEAkNNOh+jLIgjxzGxA9dRV 91 | 62M91qaTyi8eDkJV+wgx4taaxZP7Jt5qwCSvjegz/5m01wOZ88hbNxx+XxQhVJK4 92 | SKZFO/I07Sfwh2oeOi0maeBdrYGiY09ZtiJuFRU3FBV3irZHU4zyRBh+VY5HyITX 93 | 12JXPWp+JC7WhkG5QiuLzNECgYEA15OBzICLpx6Es4clAVT6JaSzJcyZM9MyyuOl 94 | e2ubbrpJCK/9ZBIvIPzMj/e0wiSH1wzeRrSM+ud7tkcSfk6ytptsIN67KSOoD3b3 95 | VNCStEU7ABe5eBG1cRzeI52MyYWpNYBzzyNMSacBvWz9hMD6ivCn44pAtGfNHclw 96 | KKNYvxECgYBOamf25md9Jy6rtQsJVEJWw+8sB4lBlKEEadc5qekR7ZQ0hwj8CnTm 97 | WOo856ynI28Sog62iw8F/do/z0B29RuGuxw+prkBkn3lg/VQXEitzqcYvota6osa 98 | 8XSfaPiTyQwWpzbFNZzzemlTsIDiF3UqwkHvWaMYPDf4Ng3cokPPxw== 99 | -----END RSA PRIVATE KEY----- 100 | 101 | requires_https: true 102 | 103 | 104 | 105 | scim: 106 | users: 107 | - rabbit_admin|rabbit_admin|scim.read,openid,rabbitmq.read:*/*,rabbitmq.write:*/*,rabbitmq.configure:*/*,rabbitmq.tag:administrator 108 | - rabbitmq_management|rabbitmq_management|scim.read,openid,rabbitmq.read:*/*,rabbitmq.write:*/*,rabbitmq.configure:*/*,rabbitmq.tag:management 109 | - rabbit_monitor|rabbit_monitor|scim.read,openid,rabbitmq.tag:monitoring 110 | - rabbit_prod_1|rabbit_prod_1|scim.read,openid,rabbit_prod.read:*/*,rabbit_prod.write:*/*,rabbit_prod.configure:*/*,rabbit_prod.tag:administrator 111 | - rabbit_dev_1|rabbit_dev_1|scim.read,openid,rabbit_dev.read:*/*,rabbit_dev.write:*/*,rabbit_dev.configure:*/*,rabbit_dev.tag:administrator 112 | 113 | groups: 114 | 'rabbitmq.read:*/*': Read all 115 | 'rabbitmq.write:*/*': Write all 116 | 'rabbitmq.configure:*/*': Configure all 117 | 'rabbitmq.tag:management': Management 118 | 'rabbitmq.tag:monitoring': Monitoring 119 | 'rabbitmq.tag:administrator': Administrator 120 | 'rabbit_dev.read:*/*': Read all 121 | 'rabbit_dev.write:*/*': Write all 122 | 'rabbit_dev.configure:*/*': Configure all 123 | 'rabbit_dev.tag:management': Management 124 | 'rabbit_dev.tag:monitoring': Monitoring 125 | 'rabbit_dev.tag:administrator': Administrator 126 | 'rabbit_prod.read:*/*': Read all 127 | 'rabbit_prod.write:*/*': Write all 128 | 'rabbit_prod.configure:*/*': Configure all 129 | 'rabbit_prod.tag:management': Management 130 | 'rabbit_prod.tag:monitoring': Monitoring 131 | 'rabbit_prod.tag:administrator': Administrator 132 | 133 | 134 | sslCertificate: | 135 | -----BEGIN CERTIFICATE----- 136 | MIIDvjCCAqagAwIBAgIBATANBgkqhkiG9w0BAQsFADBLMTowOAYDVQQDDDFUTFNH 137 | ZW5TZWxmU2lnbmVkUm9vdENBIDIwMjQtMTAtMjFUMDk6MDg6MjguMTEyNzk5MQ0w 138 | CwYDVQQHDAQkJCQkMB4XDTI0MTAyMTA3MDgyOFoXDTM0MTAxOTA3MDgyOFowHzEM 139 | MAoGA1UEAwwDdWFhMQ8wDQYDVQQKDAZzZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUA 140 | A4IBDwAwggEKAoIBAQC2GW95QN84/n+uyIWo3m9e74FA0htx5QPLLaKSLbfAw4CX 141 | x2nAOYZriln8q6r7SMaVLAb/mYL8DDtgpZZTJbscLUXkDhRYeSpo2+T5FwcaFxUN 142 | 4g0FgOQ63fjZrmVzQcZ79fdnPXjCI9MoKls7Bm3FPaVgXIquS+Hwp5EzNvOIpmM7 143 | TRt7d1Vu1G9HQgnZy88JSBiuFXEqNnvVcX6x/t6ORMhvfBPV3UvMfEug35Z0PoW5 144 | hIk4hEwn1WEnv0RVjtcGOQ/XG7aZS1lcalseBuA0lpiqsRfFv+WEG2iEpNPCC31y 145 | e9I7kLACcH1c5hWx4FUOPZifa18D+Ld7ylNTLOcXAgMBAAGjgdgwgdUwCQYDVR0T 146 | BAIwADALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwMwYDVR0RBCww 147 | KoIDdWFhghhtcm9zYWxlczBMVkRRLnZtd2FyZS5jb22CCWxvY2FsaG9zdDAdBgNV 148 | HQ4EFgQUFefeg8vgwGcYINxqkp+elRSg1KowHwYDVR0jBBgwFoAU+t17e8Lzl3Ty 149 | kw0iAZGkFHX9JZUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC1zZXJ2ZXI6 150 | ODAwMC9iYXNpYy5jcmwwDQYJKoZIhvcNAQELBQADggEBAE4Ut555AE2oHfXWSY9J 151 | HLUKK6E5uU/b+bx5hu5BxRvmiSSiJBiCk4ASkVfcafiLqoK+yQ9GG7w1Lk8SWbKL 152 | ZzrXsGgnkyVw2v4/xmezpRKEEAGGCcUMzGab6CU6SKOZSOAbokSKuzH3na2iNM0E 153 | U/EZSHwiSTUk8DTQQB6wztB5n4gw51qnWkLIzn6Kt87ztJ+kmf2qds/0Mz20pHz9 154 | VstHhCOdrRpwosDkP1cmPVxtb6ii02PbVmseUa4gGyomRQFFhorKkKVAo5tn+9Vt 155 | lLnaHvy0ZfB26tGqA098vjkvsk+BL7b8rKIuckiEWWzDKdaWikJPz2QhPuqakZad 156 | jTE= 157 | -----END CERTIFICATE----- 158 | 159 | 160 | sslPrivateKey: | 161 | -----BEGIN PRIVATE KEY----- 162 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC2GW95QN84/n+u 163 | yIWo3m9e74FA0htx5QPLLaKSLbfAw4CXx2nAOYZriln8q6r7SMaVLAb/mYL8DDtg 164 | pZZTJbscLUXkDhRYeSpo2+T5FwcaFxUN4g0FgOQ63fjZrmVzQcZ79fdnPXjCI9Mo 165 | Kls7Bm3FPaVgXIquS+Hwp5EzNvOIpmM7TRt7d1Vu1G9HQgnZy88JSBiuFXEqNnvV 166 | cX6x/t6ORMhvfBPV3UvMfEug35Z0PoW5hIk4hEwn1WEnv0RVjtcGOQ/XG7aZS1lc 167 | alseBuA0lpiqsRfFv+WEG2iEpNPCC31ye9I7kLACcH1c5hWx4FUOPZifa18D+Ld7 168 | ylNTLOcXAgMBAAECggEBAKPmUuI1FHVtA6lijIMI6f7t3U1ljxQ9R+PZCEk/4vMa 169 | RCTYdINyg11J4mK8dKHFyA892HK4Th/kNpFvmNTv0fCzgwOX9JIJRLWqrfXQ1zCR 170 | c/7R5lx8vW+KmM/82w0ZN7gdE/gVaRp8OjMdpI2E5MoyCSapRJ1KaWs8t0D8hcgI 171 | TPu2BVHQb6k+bM0cCjhsK7bD+L8IsLX2OK7FTB3kXtCv0BoPT40UgY1jPx60geEp 172 | 0rzsI9hjOfhcazs1ukFi5kOoMXBGaLYURDbNZSFQVEKaHPM8dDkJJwTLYTUK7nHI 173 | Vb+XdEe0nvmJYOiQxWzM1KsU+HlI7bd2CoUOxcY8X1ECgYEA6BJxrT0PQtZiPwQM 174 | NKF5TaIZrVzrWJB/i3yQr7Oin4HqZJI8O94EgHKvzMD1zEOFxWxGvIX3THmJOBHD 175 | F2F06S5l3RFcVofOQpW54j/WzwMZGrLfCIYIRxPnhGtSl0BRZUplZ3vfubLxexO/ 176 | 85DPmAuwF3XwR/MAK6pwB3o1Z58CgYEAyN/1jFrgqhqqYcHZtAaxgZOxb3dMLt7E 177 | hj+sACxHdHSOgCt+C5phtT94IjeYOytGvujimv+fmj7H9GaPgGJPHLmaoHZe6DtW 178 | uP58PKcL/bhmYkKnAWBWxd3rQf3dvdjLtlN0qMmbw0+sKxyeRGhpskTdP56BavAy 179 | W8vB3GkurYkCgYBLw9nBCTI2S+9/Sz8A38bOhaGEa9WZ8HLzgxNpiWgKU0vG0cdA 180 | dFdb6BVk74pPyauerJ7bZZE7MmKOH55lv7d/eVpgNg7DYUsBighJyTXEF+rWQJd4 181 | HOoO6nynSrKIFsN8IjHA+zwrUDRuTiBY0Go15Xrz7dkoZDkmCFrS1h8hWQKBgQCw 182 | aNcJWyog2Wg2j/qz+ojbJizWmmtiYisvRy2zvS9Hm7El6Iw6fms+tK25Rx+/HuNz 183 | d6zCuKme2XHbNlLiSfP2Yx3ju/DffHVN49iRn5aNTOtFcgme0M+D17/q5ZteRc2p 184 | oqM6NExB+29VMT3hD917PLUdUQOROb7QFSJ8gjcHGQKBgQC7+plyNfsrCdmkZt4J 185 | LVp1zSFzJDpqjJEeWQO+GKOjwu4S9ZK7FGOsubgYnDx3p4kVVesd+HgX6g81dOVm 186 | syoJ4H4QsoNts3VyTdY4XZz9uZTLd+JQ2TMN09E1KFL5J0q7mzuEs8CZQJ4GxOX0 187 | Miiydk9r5hmy58oDFOWGuxkatg== 188 | -----END PRIVATE KEY----- 189 | 190 | 191 | 192 | oauth: 193 | # Always override clients on startup 194 | client: 195 | override: true 196 | 197 | # List of OAuth clients 198 | clients: 199 | admin: 200 | id: admin 201 | secret: adminsecret 202 | authorized-grant-types: client_credentials 203 | scope: none 204 | authorities: uaa.admin,clients.admin,clients.read,clients.write,clients.secret,scim.write,scim.read,uaa.resource 205 | mgt_api_client: 206 | id: mgt_api_client 207 | secret: mgt_api_client 208 | authorized-grant-types: client_credentials 209 | authorities: rabbitmq.tag:monitoring 210 | rabbit_idp_user: 211 | id: rabbit_idp_user 212 | secret: rabbit_idp_user 213 | authorized-grant-types: client_credentials 214 | authorities: uaa.resource,rabbitmq.tag:administrator 215 | redirect-uri: https://localhost:3000 216 | autoapprove: true 217 | allowpublic: true 218 | rabbit_client_code: 219 | id: rabbit_client_code 220 | secret: rabbit_client_code 221 | authorized-grant-types: authorization_code 222 | scope: rabbitmq.*,openid,profile 223 | authorities: uaa.resource,rabbitmq 224 | redirect-uri: http://localhost:15672 225 | allowpublic: true 226 | mgt_api_client_2: 227 | id: mgt_api_client_2 228 | secret: mgt_api_client_2 229 | authorized-grant-types: client_credentials 230 | authorities: api://rabbitmq:management 231 | producer: 232 | id: producer 233 | secret: producer_secret 234 | authorities: rabbitmq.write:*/*,rabbitmq.read:*/*,rabbitmq.configure:*/* 235 | authorized-grant-types: client_credentials 236 | prod_producer: 237 | id: prod_producer 238 | secret: prod_producer 239 | authorities: rabbit_prod.write:*/*,rabbit_prod.read:*/*,rabbit_prod.configure:*/* 240 | authorized-grant-types: client_credentials 241 | rabbit_prod_1: 242 | id: rabbit_prod_1 243 | secret: rabbit_prod_1 244 | scope: rabbit_prod.*,openid,profile 245 | authorities: uaa.resource,rabbit_prod 246 | authorized-grant-types: authorization_code 247 | redirect-uri: http://localhost:15672 248 | allowpublic: true 249 | rabbit_dev_1: 250 | id: rabbit_dev_1 251 | secret: rabbit_dev_1 252 | scope: rabbit_dev.*,openid,profile 253 | authorities: uaa.resource,rabbit_dev 254 | authorized-grant-types: authorization_code 255 | redirect-uri: http://localhost:15672 256 | allowpublic: true 257 | uaa_producer: 258 | id: uaa_producer 259 | secret: uaa_producer_secret 260 | authorities: rabbitmq-4-uaa.write:*/*,rabbitmq-4-uaa.read:*/*,rabbitmq-4-uaa.configure:*/* 261 | authorized-grant-types: client_credentials 262 | consumer: 263 | id: consumer 264 | secret: consumer_secret 265 | authorities: rabbitmq.read:*/*,rabbitmq.configure:*/*,rabbitmq.write:*/x-*,rabbitmq.write:*/q-* 266 | authorized-grant-types: client_credentials 267 | jms_producer: 268 | id: jms_producer 269 | secret: jms_producer_secret 270 | authorities: rabbitmq.write:%2F/*,rabbitmq.read:%2F/*,rabbitmq.configure:%2F/*,rabbitmq.configure:*/jms.durable.queues,rabbitmq.write:*/jms.durable.queues,rabbitmq.read:*/jms.durable.queues 271 | authorized-grant-types: client_credentials 272 | jms_consumer: 273 | id: jms_consumer 274 | secret: jms_consumer_secret 275 | authorities: rabbitmq.read:*/*,rabbitmq.configure:*/*,rabbitmq.write:*/x-*,rabbitmq.write:*/q-*,rabbitmq.write:*/jms.durable.queues 276 | authorized-grant-types: client_credentials 277 | producer_with_roles: 278 | id: producer_with_roles 279 | secret: producer_with_roles_secret 280 | authorities: rabbitmq.*,api://rabbitmq:producer,api://rabbitmq:Administrator 281 | authorized-grant-types: client_credentials 282 | consumer_with_roles: 283 | id: consumer_with_roles 284 | secret: consumer_with_roles_secret 285 | authorities: rabbitmq.* api://rabbitmq:Read.All,api://rabbitmq:Configure.All,api://rabbitmq:Write.All 286 | authorized-grant-types: client_credentials 287 | -------------------------------------------------------------------------------- /jms-client/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################ 2 | # STEP 1 build executable binary 3 | ############################ 4 | 5 | FROM maven:3.8.4-jdk-8 as builder 6 | 7 | WORKDIR /workspace 8 | 9 | COPY src ./src 10 | COPY pom.xml ./ 11 | 12 | RUN mvn 13 | 14 | 15 | ############################ 16 | # STEP 2 build a small image 17 | ############################ 18 | FROM openjdk:8 19 | WORKDIR / 20 | # Copy our static executable. 21 | COPY --from=builder /workspace/target . 22 | ENTRYPOINT ["java", "-jar", "jms-client-1.0-SNAPSHOT-jar-with-dependencies.jar"] 23 | -------------------------------------------------------------------------------- /jms-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.vmware.rabbitmq 8 | jms-client 9 | 1.0-SNAPSHOT 10 | 11 | jms-client 12 | 13 | 14 | UTF-8 15 | 1.8 16 | 1.8 17 | 5.14.2 18 | 1.7.36 19 | 20 | 21 | 22 | 23 | com.rabbitmq.jms 24 | rabbitmq-jms 25 | 2.4.0 26 | 27 | 28 | org.slf4j 29 | slf4j-api 30 | ${slf4j-api.version} 31 | 32 | 33 | 34 | 35 | install 36 | 37 | 38 | 39 | org.apache.maven.plugins 40 | maven-assembly-plugin 41 | 42 | 43 | package 44 | 45 | single 46 | 47 | 48 | 49 | 50 | 51 | com.vmware.rabbitmq.App 52 | 53 | 54 | 55 | 56 | jar-with-dependencies 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /jms-client/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | java -jar target/jms-client-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /jms-client/src/main/java/com/vmware/rabbitmq/App.java: -------------------------------------------------------------------------------- 1 | package com.vmware.rabbitmq; 2 | 3 | import com.rabbitmq.jms.admin.RMQConnectionFactory; 4 | 5 | import javax.jms.*; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.util.concurrent.Semaphore; 8 | 9 | public class App { 10 | private static final int RABBIT_PORT = 5672; 11 | private static final int RABBIT_TLS_PORT = 5671; 12 | private final Command command; 13 | private boolean secure; 14 | private String token; 15 | private int qbrMax; 16 | private String queueName; 17 | private String message = "hello world"; 18 | private String hostname; 19 | 20 | enum Command { pub, sub } 21 | 22 | public App(Command command, String hostname, String token, String queueName, boolean secure) { 23 | this.command = command; 24 | this.hostname = hostname; 25 | this.queueName = queueName; 26 | this.secure = secure; 27 | this.token = token; 28 | this.qbrMax = 0; 29 | } 30 | 31 | public static void main( String[] args ) throws JMSException, InterruptedException { 32 | if (args.length < 1) { 33 | throw new RuntimeException("Missing 1st parameter [pub or sub]"); 34 | } 35 | new App(Command.valueOf(args[0]), hostname(), token(), queueName(), isSecure()).run(); 36 | } 37 | 38 | private static String queueName() { 39 | String queue = System.getenv("QUEUE"); 40 | return queue != null ? queue : "jms-client.test"; 41 | } 42 | 43 | private static String token() { 44 | return System.getenv("TOKEN"); 45 | } 46 | 47 | private static String hostname() { 48 | String hostname = System.getenv("HOSTNAME"); 49 | return hostname != null ? hostname : "localhost"; 50 | } 51 | private static boolean isSecure() { 52 | String secureOption = System.getenv("SECURE"); 53 | return secureOption != null && Boolean.parseBoolean(secureOption); 54 | } 55 | 56 | private void sendQueueMessage() throws JMSException { 57 | QueueConnection conn = getQueueConnectionFactory().createQueueConnection("", token); 58 | try { 59 | conn.start(); 60 | QueueSession session = conn.createQueueSession(false, Session.DUPS_OK_ACKNOWLEDGE); 61 | Queue queue = session.createQueue(queueName); 62 | 63 | QueueSender sender = session.createSender(queue); 64 | sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 65 | sender.send(textMessage(session)); 66 | System.out.println("Sent message"); 67 | sender.close(); 68 | session.close(); 69 | }finally { 70 | conn.stop(); 71 | } 72 | } 73 | 74 | 75 | private Message textMessage(QueueSession session) throws JMSException { 76 | return session.createTextMessage(message); 77 | 78 | } 79 | public void run() throws JMSException, InterruptedException { 80 | System.out.printf("Running command %s\n", command); 81 | 82 | switch(command) { 83 | case pub: 84 | sendQueueMessage(); 85 | break; 86 | case sub: 87 | subscribeQueue(); 88 | break; 89 | } 90 | } 91 | 92 | private void subscribeQueue() throws JMSException, InterruptedException { 93 | QueueConnection conn = getQueueConnectionFactory().createQueueConnection("", token); 94 | try { 95 | conn.start(); 96 | QueueSession session = conn.createQueueSession(false, Session.DUPS_OK_ACKNOWLEDGE); 97 | Queue queue = session.createQueue(queueName); 98 | QueueReceiver receiver = session.createReceiver(queue); 99 | 100 | final Semaphore sem = new Semaphore(0); 101 | receiver.setMessageListener(message -> { 102 | System.out.println("Received message"); 103 | if (message instanceof TextMessage) { 104 | try { 105 | String msgBody = ((TextMessage) message).getText(); 106 | if (msgBody.equals("exit")) sem.release(); 107 | } catch (JMSException e) { 108 | 109 | } 110 | } 111 | }); 112 | sem.acquire(); 113 | session.close(); 114 | }finally { 115 | conn.stop(); 116 | } 117 | } 118 | 119 | private QueueConnectionFactory getQueueConnectionFactory(){ 120 | return (QueueConnectionFactory)getConnectionFactory(); 121 | } 122 | private ConnectionFactory getConnectionFactory() { 123 | RMQConnectionFactory rmqCF = new RMQConnectionFactory() { 124 | private static final long serialVersionUID = 1L; 125 | @Override 126 | public Connection createConnection(String userName, String password) throws JMSException { 127 | if (!secure) { 128 | this.setPort(RABBIT_PORT); 129 | } else { 130 | this.setPort(RABBIT_TLS_PORT); 131 | } 132 | return super.createConnection(userName, password); 133 | } 134 | }; 135 | if (secure) { 136 | try { 137 | rmqCF.useSslProtocol(); 138 | } catch (NoSuchAlgorithmException e) { 139 | throw new RuntimeException(e); 140 | } 141 | } 142 | rmqCF.setHost(hostname); 143 | rmqCF.setQueueBrowserReadMax(qbrMax); 144 | return rmqCF; 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /jwts/consumer-roles-in-extra-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "extra_scope": [ 4 | "api://rabbitmq:Read.All", 5 | "api://rabbitmq:Configure.All", 6 | "api://rabbitmq:Write.All" 7 | ], 8 | "aud": [ 9 | "rabbitmq" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /jwts/consumer-roles-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "scope": [ 3 | "api://rabbitmq:Read.All", 4 | "api://rabbitmq:Configure.All", 5 | "api://rabbitmq:Write.All" 6 | ], 7 | "aud": [ 8 | "rabbitmq" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /jwts/mgt-api-client.json: -------------------------------------------------------------------------------- 1 | { 2 | "sub": "mgt-api-client", 3 | "scope": [ 4 | "rabbitmq.write:*/*/*", 5 | "rabbitmq.configure:*/*/*", 6 | "rabbitmq.read:*/*/*", 7 | "rabbitmq.tag:management" 8 | ], 9 | "aud": [ 10 | "rabbitmq" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /jwts/producer-role-in-extra-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "extra_scope": [ 3 | "api://rabbitmq:producer" 4 | ], 5 | "aud": [ 6 | "rabbitmq" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /jwts/producer-roles-in-extra-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "extra_scope": [ 3 | "api://rabbitmq:producer", 4 | "api://rabbitmq:Administrator" 5 | ], 6 | "aud": [ 7 | "rabbitmq" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /jwts/producer-roles-in-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "sub" : "producer", 3 | "scope": [ 4 | "api://rabbitmq:producer", 5 | "api://rabbitmq:Administrator" 6 | ], 7 | "aud": [ 8 | "rabbitmq" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /jwts/producer-without-scopes.json: -------------------------------------------------------------------------------- 1 | { 2 | "sub" : "producer", 3 | "aud": [ 4 | "rabbitmq" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /jwts/rar-token.json: -------------------------------------------------------------------------------- 1 | { 2 | "authorization_details": [ 3 | { "type" : "rabbitmq", 4 | "locations": ["cluster:rabbitmq"], 5 | "actions": ["tag:administrator", "read", "write", "configure" ] 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /jwts/scope-and-extra-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "sub": "rabbitmq-client-code", 3 | "scope": [ 4 | "rabbitmq.write:*/*/*", 5 | "rabbitmq.configure:*/*/*", 6 | "rabbitmq.read:*/*/*" 7 | ], 8 | "extra_scope": "rabbitmq.tag:administrator", 9 | "aud": [ 10 | "rabbitmq" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /jwts/scope-and-roles-in-extra-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "sub": "rabbitmq-client-code", 3 | "extra_scope": ["api://rabbitmq:Administrator"], 4 | "aud": [ 5 | "rabbitmq" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /jwts/scopes-for-mqtt.json: -------------------------------------------------------------------------------- 1 | { 2 | "scope": [ 3 | "rabbitmq.write:*/*/*", 4 | "rabbitmq.configure:*/*/*", 5 | "rabbitmq.read:*/*/*" 6 | 7 | ], 8 | "extra_scope": "rabbitmq.tag:administrator", 9 | "aud": [ 10 | "rabbitmq" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /oauth-resource-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node 2 | EXPOSE 8888 3 | WORKDIR /home/app 4 | RUN npm install --save express 5 | RUN npm install --save uuid 6 | RUN npm install --save jose 7 | RUN npm install --save axios 8 | RUN npm install --save oidc-client-ts 9 | COPY * /home/app 10 | CMD [ "npm", "start" ] 11 | -------------------------------------------------------------------------------- /oauth-resource-app/Makefile: -------------------------------------------------------------------------------- 1 | .ONESHELL:# single shell invocation for all lines in the recipe 2 | SHELL = bash# we depend on bash expansion for e.g. queue patterns 3 | 4 | .DEFAULT_GOAL = help 5 | 6 | 7 | ### TARGETS ### 8 | 9 | help: 10 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 11 | 12 | 13 | build-server-image: ## Build server image 14 | @docker build . -t ui:latest 15 | 16 | run-server: stop-server ## Run server 17 | @docker run --name ui -p 15672:8888 -v /Users/mrosales/gm-work/rabbitmq-oauth2-tutorial/oauth-resource-app/public:/home/app/public ui:latest 18 | 19 | stop-server: ## Stop server 20 | @(docker stop ui || true && docker rm ui || true) 21 | 22 | build-and-run: build-server-image run-server ## Build and run 23 | -------------------------------------------------------------------------------- /oauth-resource-app/public/common.js: -------------------------------------------------------------------------------- 1 | 2 | //import {UserManager} from "./scripts/oidc-client-ts/oidc-client-ts.js" 3 | // import {axios} from "./scripts/axios/axios.min.js" 4 | 5 | 6 | const idp_base_url = "http://localhost:8080/uaa" 7 | rabbit_port = window.location.port ? ":" + window.location.port : "" 8 | rabbit_base_uri = window.location.protocol + "//" + window.location.hostname + rabbit_port 9 | rabbit_redirect_uri = rabbit_base_uri 10 | rabbit_login_uri = rabbit_base_uri + "/login.html" 11 | 12 | const settings = { 13 | //userStore: new WebStorageStateStore({ store: window.localStorage }), 14 | authority: idp_base_url, 15 | client_id: "rabbit_client_code", 16 | client_secret: "rabbit_client_code", 17 | redirect_uri: rabbit_redirect_uri + "/login-callback.html", 18 | post_logout_redirect_uri: rabbit_redirect_uri * "/logout-callback.html", 19 | response_type: "code", 20 | scope: "openid profile rabbitmq.*", 21 | resource: "rabbitmq", 22 | //scope: 'openid profile api offline_access', 23 | 24 | //automaticSilentRenew: false, 25 | //validateSubOnSilentRenew: true, 26 | //silentRequestTimeout: 10000, 27 | 28 | //loadUserInfo: true, 29 | //monitorAnonymousSession: true, 30 | filterProtocolClaims: true, 31 | revokeAccessTokenOnSignout: true, 32 | 33 | }; 34 | 35 | oidc.Log.setLogger(console); 36 | oidc.Log.setLevel(oidc.Log.INFO); 37 | 38 | function log() { 39 | message = "" 40 | Array.prototype.forEach.call(arguments, function(msg) { 41 | if (msg instanceof Error) { 42 | msg = "Error: " + msg.message; 43 | } 44 | else if (typeof msg !== "string") { 45 | msg = JSON.stringify(msg, null, 2); 46 | } 47 | message += msg 48 | }); 49 | console.log(message) 50 | } 51 | 52 | 53 | var mgr = new oidc.UserManager(settings); 54 | 55 | 56 | function registerCallbacks() { 57 | mgr.events.addUserLoaded(function (user) { 58 | console.log("addUserLoaded=> ", user); 59 | mgr.getUser().then(function() { 60 | console.log("getUser loaded user after userLoaded event fired"); 61 | }); 62 | }); 63 | mgr.events.addUserUnloaded(function (e) { 64 | console.log("addUserUnloaded=> ", e); 65 | }); 66 | 67 | mgr.events.addUserSignedIn(function (e) { 68 | log("addUserSignedIn=> " , e); 69 | }); 70 | mgr.events.addUserSignedOut(function (e) { 71 | log("addUserSignedOut=> ", e); 72 | }); 73 | 74 | } 75 | function isLoggedIn() { 76 | return mgr.getUser().then(user => { 77 | if (!user) { 78 | return { "loggedIn": false }; 79 | } 80 | return { "user": user, "loggedIn": !user.expired }; 81 | }); 82 | } 83 | 84 | 85 | function initiateLogin() { 86 | mgr.signinRedirect({ state: { foo: "bar" } /*, useReplaceToNavigate: true*/ }).then(function() { 87 | log("signinRedirect done"); 88 | }).catch(function(err) { 89 | console.error(err); 90 | log(err); 91 | }); 92 | } 93 | function redirectToHome() { 94 | location.href = "/index.html" 95 | } 96 | function redirectToLogin() { 97 | location.href = "/login.html" 98 | } 99 | function completeLogin() { 100 | mgr.signinRedirectCallback().then(user => redirectToHome()).catch(function(err) { 101 | console.error(err); 102 | log(err); 103 | }); 104 | } 105 | 106 | function initiateLogout() { 107 | mgr.signoutRedirect(); 108 | } 109 | function completeLogout() { 110 | mgr.signoutRedirectCallback().then(_ => redirectToLogin()); 111 | } 112 | -------------------------------------------------------------------------------- /oauth-resource-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitmq/rabbitmq-oauth2-tutorial/e1b959370ab7b626a0cb7635957be8ea623a3bac/oauth-resource-app/public/favicon.ico -------------------------------------------------------------------------------- /oauth-resource-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | RabbitMQ 8 | with scopes 9 | 10 | 11 | 12 | 13 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /oauth-resource-app/public/login-callback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /oauth-resource-app/public/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | RabbitMQ 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /oauth-resource-app/public/logout-callback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /oauth-resource-app/src/app.js: -------------------------------------------------------------------------------- 1 | // app.js 2 | const express = require("express") 3 | 4 | const app = express() 5 | app.use(express.static('public')) 6 | app.use('/scripts/jose', express.static(__dirname + '/node_modules/jose/dist/browser/')); 7 | app.use('/scripts/axios', express.static(__dirname + '/node_modules/axios/dist/')); 8 | app.use('/scripts/oidc-client-ts', express.static(__dirname + '/node_modules/oidc-client-ts/dist/browser/')); 9 | 10 | module.exports = app 11 | -------------------------------------------------------------------------------- /oauth-resource-app/src/server.js: -------------------------------------------------------------------------------- 1 | 2 | const app = require("./app") 3 | const port = 8888 4 | 5 | 6 | app.listen(port, () => console.log(`The server is listening on port ${port}`)) 7 | -------------------------------------------------------------------------------- /pika-client/producer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # pylint: disable=C0111,C0103,R0205 3 | import datetime 4 | import time 5 | import pika 6 | import requests 7 | import sys 8 | 9 | print('pika version: %s' % pika.__version__) 10 | 11 | # You need Pika 1.3 12 | # Get the access token 13 | def new_access_token(): 14 | headers = {'Content-Type': 'application/x-www-form-urlencoded'} 15 | r = requests.post('http://localhost:8080/realms/test/protocol/openid-connect/token', headers=headers, 16 | data={'client_id': sys.argv[1], 'client_secret': sys.argv[2], 17 | 'grant_type': 'client_credentials'}) 18 | 19 | dictionary = r.json() 20 | return dictionary["access_token"] 21 | 22 | 23 | credentials = pika.PlainCredentials('', new_access_token()) 24 | 25 | connection = pika.BlockingConnection(pika.ConnectionParameters( 26 | virtual_host="/", 27 | credentials=credentials)) 28 | 29 | main_channel = connection.channel() 30 | main_channel.queue_declare(queue="keycloak", auto_delete=False, durable=True, 31 | arguments={"x-queue-type": "quorum"}) 32 | 33 | _COUNT_ = 100 34 | 35 | tnow = datetime.datetime.now() 36 | last_update = datetime.datetime.now() 37 | 38 | for i in range(0, _COUNT_): 39 | msg = 'MyMessage {}'.format(i) 40 | print('Sending message: {}'.format(msg)) 41 | # Update the secret each minute. Supposed that Access Token Lifespan is 1 minute. 42 | 43 | if (datetime.datetime.now() - last_update).total_seconds() > 55: 44 | last_update = datetime.datetime.now() 45 | print('updating secret {}'.format((datetime.datetime.now() - tnow).total_seconds() / 60)) 46 | connection.update_secret(new_access_token(), 'secret') 47 | main_channel.basic_publish( 48 | exchange='', 49 | routing_key='keycloak', 50 | body=msg, 51 | properties=pika.BasicProperties(content_type='application/json')) 52 | # Wait for the message to be sent 53 | # just to wait the Access Token Lifespan expires 54 | time.sleep(5) 55 | 56 | connection.close() 57 | -------------------------------------------------------------------------------- /stream_dot_net/Keycloak/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ -------------------------------------------------------------------------------- /stream_dot_net/Keycloak/Keycloak.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /stream_dot_net/Keycloak/Program.cs: -------------------------------------------------------------------------------- 1 | // You need RabbitMQ.Stream.Client 1.8.0-rc.2 or later 2 | // RabbitMQ 3.13.0 or later 3 | // Keycloak RabbitMQ stream client example 4 | // NOTE: By default there is not TTL for the access token, you need to set it up in the Keycloak realm 5 | // for the client producer 6 | using System.Buffers; 7 | using System.Net; 8 | using System.Text; 9 | using RabbitMQ.Stream.Client; 10 | using RabbitMQ.Stream.Client.Reliable; 11 | 12 | Console.WriteLine("Keycloak Example: RabbitMQ.Stream.Client"); 13 | 14 | var system = await StreamSystem.Create(new StreamSystemConfig() 15 | { 16 | UserName = "producer", 17 | Password = await NewAccessToken(), 18 | VirtualHost = "/", 19 | }); 20 | 21 | 22 | const string stream = "test-keycloak"; 23 | await system.CreateStream(new StreamSpec(stream) 24 | { 25 | MaxLengthBytes = 1_000_000, 26 | }); 27 | 28 | var start = DateTime.Now; 29 | var completed = new TaskCompletionSource(); 30 | 31 | _ = Task.Run(async () => 32 | { 33 | while (completed.Task.Status != TaskStatus.RanToCompletion) 34 | { 35 | await Task.Delay(TimeSpan.FromSeconds(1)); 36 | // Suppose you have the access token for 60 seconds 37 | if (start.AddSeconds(50) >= DateTime.Now) continue; 38 | // Here we are updating the secret to the pool 39 | Console.WriteLine($"{DateTime.Now} - Updating the secret...."); 40 | await system.UpdateSecret(await NewAccessToken()).ConfigureAwait(false); 41 | start = DateTime.Now; 42 | } 43 | }); 44 | 45 | var consumer = await Consumer.Create(new ConsumerConfig(system, stream) 46 | { 47 | OffsetSpec = new OffsetTypeFirst(), 48 | MessageHandler = (_, _, _, message) => 49 | { 50 | Console.WriteLine( 51 | $"{DateTime.Now} - Received: {Encoding.UTF8.GetString(message.Data.Contents.ToArray())} "); 52 | return Task.CompletedTask; 53 | } 54 | }); 55 | 56 | 57 | var producer = await Producer.Create(new ProducerConfig(system, stream)); 58 | // Here we are sending 10 messages per second for 5 minutes 59 | // Given the access token is valid for 60 seconds, we should see the token being updated 60 | // and the producer continuing to send messages 61 | for (var i = 0; i < 10 * 5; i++) 62 | { 63 | await producer.Send(new Message(Encoding.UTF8.GetBytes($"Hello KeyCloak! {i}"))); 64 | await Task.Delay(TimeSpan.FromSeconds(1)); 65 | Console.WriteLine($"{DateTime.Now} - Sent: Hello KeyCloak! {i}"); 66 | } 67 | 68 | completed.SetResult(true); 69 | Console.WriteLine("Closing..."); 70 | await consumer.Close(); 71 | await producer.Close(); 72 | await system.Close(); 73 | Console.WriteLine("Closed."); 74 | return; 75 | 76 | async Task NewAccessToken() 77 | { 78 | var data = new[] 79 | { 80 | new KeyValuePair("client_id", "producer"), 81 | new KeyValuePair("client_secret", "kbOFBXI9tANgKUq8vXHLhT6YhbivgXxn"), 82 | new KeyValuePair("grant_type", "client_credentials"), 83 | }; 84 | var httpRequestMessage = new HttpRequestMessage 85 | { 86 | Method = HttpMethod.Post, 87 | RequestUri = new Uri("http://localhost:8080/realms/test/protocol/openid-connect/token"), 88 | Headers = 89 | { 90 | { 91 | HttpRequestHeader.ContentType.ToString(), "application/x-www-form-urlencoded" 92 | }, 93 | }, 94 | Content = new FormUrlEncodedContent(data) 95 | }; 96 | var client = new HttpClient(); 97 | var response = await client.SendAsync(httpRequestMessage); 98 | var responseString = await response.Content.ReadAsStringAsync(); 99 | var json = System.Text.Json.JsonDocument.Parse(responseString); 100 | var r = json.RootElement.GetProperty("access_token").GetString(); 101 | return r ?? throw new Exception("no access token"); 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /stream_dot_net/Keycloak/README.md: -------------------------------------------------------------------------------- 1 | ### Keycloak RabbitMQ stream client example 2 | 3 | This is a simple example of how to use the Keycloak [RabbitMQ stream client](https://github.com/rabbitmq/rabbitmq-stream-dotnet-client). 4 | 5 | See the section `use-cases/keycloak.md` on this repository to setup the example. 6 | --------------------------------------------------------------------------------