1"use strict";(self.webpackChunkrabbitmq_website=self.webpackChunkrabbitmq_website||[]).push([["21254"],{3380(e,t,r){r.r(t),r.d(t,{metadata:()=>a,default:()=>h,frontMatter:()=>o,contentTitle:()=>i,toc:()=>l,assets:()=>c});var a=JSON.parse('{"id":"oauth2-examples-forward-proxy","title":"Use an explicit forward proxy and Keycloak as OAuth 2.0 server","description":"\x3c!--","source":"@site/versioned_docs/version-4.3/oauth2-examples-forward-proxy.md","sourceDirName":".","slug":"/oauth2-examples-forward-proxy","permalink":"/docs/oauth2-examples-forward-proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/rabbitmq/rabbitmq-website/tree/main/versioned_docs/version-4.3/oauth2-examples-forward-proxy.md","tags":[],"version":"4.3","frontMatter":{"title":"Use an explicit forward proxy and Keycloak as OAuth 2.0 server","displayed_sidebar":"docsSidebar"},"sidebar":"docsSidebar","previous":{"title":"Multiple OAuth 2.0 Servers","permalink":"/docs/oauth2-examples-multiresource"},"next":{"title":"OAuth2 Proxy with Keycloak","permalink":"/docs/oauth2-examples-proxy"}}'),n=r(74848),s=r(28453);let o={title:"Use an explicit forward proxy and Keycloak as OAuth 2.0 server",displayed_sidebar:"docsSidebar"},i="Use an explicit forward proxy and Keycloak as OAuth 2.0 server",c={},l=[{value:"Prerequisites for Using OAuth 2 vith a forward proxy",id:"prerequisites-for-using-oauth-2-vith-a-forward-proxy",level:2},{value:"Deploy Keycloak",id:"deploy-keycloak",level:2},{value:"Start Forward Proxy",id:"start-forward-proxy",level:2},{value:"Start RabbitMQ",id:"start-rabbitmq",level:2},{value:"Access management UI",id:"access-management-ui",level:2},{value:"Access Management API",id:"access-management-api",level:2}];function d(e){let t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"use-an-explicit-forward-proxy-and-keycloak-as-oauth-20-server",children:"Use an explicit forward proxy and Keycloak as OAuth 2.0 server"})}),"\n",(0,n.jsx)(t.admonition,{type:"warning",children:(0,n.jsxs)(t.p,{children:["To run this example you need to use the commercial ",(0,n.jsx)(t.a,{href:"https://techdocs.broadcom.com/us/en/vmware-tanzu/data-solutions/tanzu-rabbitmq-oci/4-0/tanzu-rabbitmq-oci-image/overview.html",children:"Tanzu RabbitMQ docker image"}),". Support for ",(0,n.jsx)(t.strong,{children:"forward proxy"})," is a commercial feature."]})}),"\n",(0,n.jsx)(t.p,{children:"This guide explains how to set up OAuth 2.0 for RabbitMQ to access the Authorization Server via an explicit forward proxy."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Access the RabbitMQ Management UI using a browser through OAuth2 Proxy"}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-plain",children:" [ Keycloak ] \n /|\\ \n | \n 2.http request (*) | [ RabbitMQ ]\n [ forward-proxy ] <----1. http request (*)--- [ http ]\n \n"})}),"\n",(0,n.jsx)(t.p,{children:"RabbitMQ establishes an HTTP connection with Keycloak via the forward-proxy in any of\nthese situations:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["You have configured ",(0,n.jsx)(t.code,{children:"auth_oauth2.issuer"})," so that RabbitMQ downloads the OpenID configuration via the OpenID discovery endpoint."]}),"\n",(0,n.jsxs)(t.li,{children:["You have configured ",(0,n.jsx)(t.code,{children:"auth_oauth2.issuer"})," or ",(0,n.jsx)(t.code,{children:"auth_oauth2.jwks_url"})," so that RabbitMQ downloads the tokens' signing keys."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites-for-using-oauth-2-vith-a-forward-proxy",children:"Prerequisites for Using OAuth 2 vith a forward proxy"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Docker"}),"\n",(0,n.jsx)(t.li,{children:"make"}),"\n",(0,n.jsxs)(t.li,{children:["A local clone of a ",(0,n.jsx)(t.a,{href:"https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/next",children:"GitHub repository"})," for branch ",(0,n.jsx)(t.code,{children:"next"}
1)," that contains all the configuration files and scripts used on this example."]}),"\n",(0,n.jsx)(t.li,{children:"The following entries in your /etc/hosts file. Without these entries you will get DNS errors in the browser."}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"localhost keycloak rabbitmq forward-proxy\n"})}),"\n",(0,n.jsxs)(t.admonition,{type:"info",children:[(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"make start-keycloak"})," will\ngenerate the TLS certificate and private keys as necessary. These certificates have an expiration date."]}),(0,n.jsxs)(t.p,{children:["In you see any error messages that hint at expired or invalid certificates, stop Keycloak, run ",(0,n.jsx)(t.code,{children:"make clean-certs"})," to regenerate the certificates and private keys,\nand then restart Keycloak and the proxy."]})]}),"\n",(0,n.jsx)(t.h2,{id:"deploy-keycloak",children:"Deploy Keycloak"}),"\n",(0,n.jsxs)(t.p,{children:["Deploy keycloak on its own network called ",(0,n.jsx)(t.code,{children:"keycloak_net"})," by running:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"PROVIDER_NETWORK=keycloak_net make start-keycloak\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To access Keycloak Management UI, go to ",(0,n.jsx)(t.a,{href:"https://keycloak:8443/",children:"https://keycloak:8443/"})," and enter ",(0,n.jsx)(t.code,{children:"admin"})," as the username and password."]}),"\n",(0,n.jsxs)(t.p,{children:["There is a dedicated ",(0,n.jsx)(t.strong,{children:"Keycloak realm"})," called ",(0,n.jsx)(t.code,{children:"Test"})," configured as follows:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://keycloak:8443/admin/master/console/#/realms/test/keys",children:"rsa"})," signing-key"]}),"\n",(0,n.jsxs)(t.li,{children:["[rsa provider]",(0,n.jsx)(t.a,{href:"https://keycloak:8443/admin/master/console/#/realms/test/keys/providers",children:"https://keycloak:8443/admin/master/console/#/realms/test/keys/providers"}),")"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"rabbitmq-proxy-client"})," client"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"start-forward-proxy",children:"Start Forward Proxy"}),"\n",(0,n.jsxs)(t.p,{children:["Deploy and start the forward-proxy in two networks, ",(0,n.jsx)(t.code,{children:"keycloak_net"})," and ",(0,n.jsx)(t.code,{children:"rabbitmq_net"}),", by running:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"PROVIDER_NETWORK=keycloak_net make start-forward-proxy\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The forward proxy is configured by using ",(0,n.jsx)(t.a,{href:"https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/next/conf/forward-proxy/httpd/httpd.conf",children:"httpd.conf"}),". This type of configuration inserts the access token into the HTTP ",(0,n.jsx)(t.strong,{children:"Authorization"})," header."]}),"\n",(0,n.jsx)(t.h2,{id:"start-rabbitmq",children:"Start RabbitMQ"}),"\n",(0,n.jsxs)(t.p,{children:["Deploy RabbitMQ in its own network ",(0,n.jsx)(t.code,{children:"rabbitmq_net"})," and start it by running:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"export IMAGE=<Tanzu RabbitMQ OCI image name>\nexport IMAGE_TAG=<Tanzu RabbitMQ OCI image tag>\nMODE=forward-proxy OAUTH_PROVIDER=keycloak make start-rabbitmq\n"})}),"\n",(0,n.jsxs)(t.h2,{id:"access-management-ui",children:["Access ",(0,n.jsx)(t.a,{href:"./management/",children:"management UI"})]}),"\n",(0,n.jsxs)(t.p,{children:["Go to ",(0,n.jsx)(t.a,{href:"https://rabbitmq:15671/",children:"https://rabbitmq:15671/"}),", proceed to login, and enter the credentials\n",(0,n.jsx)(t.code,{children:"rabbit_admin"})," as the username and ",(0,n.jsx)(t.code,{children:"rabbit_admin"})," as the password when Keycloak prompts you.\nYou will be redirected back to RabbitMQ management UI."]}),"\n",(0,n.jsx)(t.p,{children:"The management UI running in the browser goes straight to keycloak.\nIn other words, it does not go via the forward-proxy. If you want the management UI to\ngo via the forward-proxy, you must configure the browser. That is beyond\nthe scope of this example."}),"\n",(0,n.jsxs)(t.p,{children:["However, in order to validate the token the management UI received from keycloak, RabbitMQ has to connect to keycloak via the forward-proxy. This is necessary in order to download the signing keys and to download the OpenID configuration if you only configured the ",(0,n.jsx)(t.code,{children:"issuer"})," URL."]}),"\n",(0,n.jsx)(t.h2,{id:"access-management-api",children:"Access Management API"}),"\n",(0,n.jsxs)(t.p,{children:["To access the management API run the following command. It uses the client ",(0,n.jsx)(t.a,{href:"https://keycloak:8443/admin/master/console/#/test/clients/c5be3c24-0c88-4672-a77a-79002fcc9a9d/settings",children:"mgt_api_client"}),", which has the scope ",(0,n.jsxs)(t.a,{href:"https://keycloak:8443/admin/master/console/#/test/client-scopes/f6e6dd62-22bf-4421-910e-e6070908764c/settings",children:["rabbitmq.tag",":administrator"]}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make curl-keycloak url=https://localhost:15671/api/overview client_id=mgt_api_client secret=LWOuYqJ8gjKg3D2U8CJZDuID3KiRZVDa realm=test\n"})})]})}function h(e={}){let{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453(e,t,r){r.d(t,{R:()=>o,x:()=>i});var a=r(96540);let n={},s=a.createContext(n);function o(e){let t=a.useContext(s);return a.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.