From 55a68d4187fd7d41f3b718f1909ead5e3d669f18 Mon Sep 17 00:00:00 2001 From: Patrick Knight Date: Fri, 27 Jan 2023 14:15:35 -0500 Subject: [PATCH 1/4] Add keycloak authentication --- app-config.yaml | 7 ++++--- packages/app/src/App.tsx | 4 ++++ packages/backend/src/plugins/auth.ts | 31 ++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index 3b5de8baa3..dbe1f92e3b 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -65,7 +65,8 @@ techdocs: auth: # see https://backstage.io/docs/auth/ to learn about auth providers - providers: {} + providers: + oauth2Proxy: {} scaffolder: # see https://backstage.io/docs/features/software-templates/configuration for software template options @@ -94,8 +95,8 @@ catalog: - allow: [User, Group] ## Uncomment these lines to add more example data - # - type: url - # target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all.yaml + - type: url + target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all.yaml ## Uncomment these lines to add an example org # - type: url diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 056402f2a8..a34f747329 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -33,6 +33,7 @@ import { AppRouter, FlatRoutes } from '@backstage/core-app-api'; import { CatalogGraphPage } from '@backstage/plugin-catalog-graph'; import { RequirePermission } from '@backstage/plugin-permission-react'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; +import { ProxiedSignInPage } from '@backstage/core-components'; const app = createApp({ apis, @@ -51,6 +52,9 @@ const app = createApp({ catalogIndex: catalogPlugin.routes.catalogIndex, }); }, + components: { + SignInPage: (props) => , + }, }); const routes = ( diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts index 77eb6aae21..d6cf41c664 100644 --- a/packages/backend/src/plugins/auth.ts +++ b/packages/backend/src/plugins/auth.ts @@ -5,6 +5,7 @@ import { } from '@backstage/plugin-auth-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; +import { DEFAULT_NAMESPACE, stringifyEntityRef } from '@backstage/catalog-model'; export default async function createPlugin( env: PluginEnvironment, @@ -49,6 +50,36 @@ export default async function createPlugin( // resolver: providers.github.resolvers.usernameMatchingUserEntityName(), }, }), + oauth2Proxy: providers.oauth2Proxy.create({ + signIn: { + async resolver({ result }, ctx) { + const name = result.getHeader('x-forwarded-preferred-username'); + if(!name) { + throw new Error('Request did not contain a user'); + } + + try { + const signedInUser = await ctx.signInWithCatalogUser({ + entityRef: { name }, + }); + + return Promise.resolve(signedInUser); + } catch (e) { + const userEntityRef = stringifyEntityRef({ + kind: 'User', + name: name, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userEntityRef, + ent: [userEntityRef], + }, + }); + } + }, + }, + }), }, }); } From 2a79b5500a1eaef04c2959723d16f7290e8dce19 Mon Sep 17 00:00:00 2001 From: Patrick Knight Date: Fri, 27 Jan 2023 16:34:52 -0500 Subject: [PATCH 2/4] Add keycloak plugin --- packages/backend/package.json | 1 + packages/backend/src/plugins/catalog.ts | 14 +++++ yarn.lock | 69 +++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 668935672d..ea57dd8a91 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -33,6 +33,7 @@ "@backstage/plugin-search-backend-module-pg": "^0.5.1", "@backstage/plugin-search-backend-node": "^1.1.1", "@backstage/plugin-techdocs-backend": "^1.5.1", + "@janus-idp/backstage-plugin-keycloak-backend": "^1.0.3", "app": "link:../app", "better-sqlite3": "^8.0.0", "dockerode": "^3.3.1", diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 876cb6bccc..8e6c743f35 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -2,11 +2,25 @@ import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; +import { KeycloakOrgEntityProvider } from '@janus-idp/backstage-plugin-keycloak-backend'; export default async function createPlugin( env: PluginEnvironment, ): Promise { const builder = await CatalogBuilder.create(env); + + builder.addEntityProvider( + KeycloakOrgEntityProvider.fromConfig(env.config, { + id: 'development', + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { hours: 1 }, + timeout: { minutes: 50 }, + initialDelay: { seconds: 15 }, + }), + }), + ); + builder.addProcessor(new ScaffolderEntitiesProcessor()); const { processingEngine, router } = await builder.build(); await processingEngine.start(); diff --git a/yarn.lock b/yarn.lock index e0a2744b8b..86c738bcdb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4039,6 +4039,21 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== +"@janus-idp/backstage-plugin-keycloak-backend@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@janus-idp/backstage-plugin-keycloak-backend/-/backstage-plugin-keycloak-backend-1.0.3.tgz#d5866a642528f19dde87d187e804604c3269bbc5" + integrity sha512-mY4zvAuHbjiShjfBMt6n/fvf3UHCCD3kQku30kaSQq+3dgRUmMK0CuokBFkgVsecYUFO5mxbXIVQ/PN9WDS66w== + dependencies: + "@backstage/backend-common" "^0.18.1" + "@backstage/backend-tasks" "^0.4.2" + "@backstage/catalog-model" "^1.1.5" + "@backstage/config" "^1.0.6" + "@backstage/plugin-catalog-backend" "^1.7.1" + "@keycloak/keycloak-admin-client" "<19.0.0" + lodash "^4.14.189" + uuid "^9.0.0" + winston "^3.2.1" + "@jest/console@^29.3.1": version "29.3.1" resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.3.1.tgz#3e3f876e4e47616ea3b1464b9fbda981872e9583" @@ -4315,6 +4330,19 @@ resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== +"@keycloak/keycloak-admin-client@<19.0.0": + version "18.0.2" + resolved "https://registry.yarnpkg.com/@keycloak/keycloak-admin-client/-/keycloak-admin-client-18.0.2.tgz#e8329830ea2bc9fc7012e31b10c06a35ab58984c" + integrity sha512-UCa+5FTPBzbbfCpC27Sb40XbNm27m78z+yax9kiw9aFwk+itiGId09bMzECBRDrqwvVMxo1vzLERLjAty3rTRg== + dependencies: + axios "^0.26.1" + camelize-ts "^1.0.8" + keycloak-js "^17.0.1" + lodash "^4.17.21" + query-string "^7.0.1" + url-join "^4.0.0" + url-template "^2.0.8" + "@keyv/memcache@^1.3.5": version "1.3.5" resolved "https://registry.yarnpkg.com/@keyv/memcache/-/memcache-1.3.5.tgz#bf7b5616b60fd997cfe5e6e5d5eb3b9fbecf39a1" @@ -7781,6 +7809,13 @@ axios@^0.21.1: dependencies: follow-redirects "^1.14.0" +axios@^0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" + integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== + dependencies: + follow-redirects "^1.14.8" + axios@^0.27.2: version "0.27.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" @@ -8410,6 +8445,11 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +camelize-ts@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/camelize-ts/-/camelize-ts-1.0.9.tgz#6ac46fbe660d18e093568ef0d56c836141b700f4" + integrity sha512-ePOW3V2qrQ0qtRlcTM6Qe3nXremdydIwsMKI1Vl2NBGM0tOo8n2xzJ7YOQpV1GIKHhs3p+F40ThI8/DoYWbYKQ== + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -11211,7 +11251,7 @@ fn.name@1.x.x: resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.14.9: +follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.14.8, follow-redirects@^1.14.9: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -13510,6 +13550,11 @@ js-sdsl@^4.1.4: resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== +js-sha256@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" + integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -13936,6 +13981,14 @@ jwt-decode@^3.1.0: resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== +keycloak-js@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/keycloak-js/-/keycloak-js-17.0.1.tgz#403ea75b3e938ddc780f99ecbd73e1b6905f826f" + integrity sha512-mbLBSoogCBX5VYeKCdEz8BaRWVL9twzSqArRU3Mo3Z7vEO1mghGZJ5IzREfiMEi7kTUZtk5i9mu+Yc0koGkK6g== + dependencies: + base64-js "^1.5.1" + js-sha256 "^0.9.0" + keyv@^4.0.0, keyv@^4.5.2: version "4.5.2" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" @@ -14306,7 +14359,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: +lodash@^4.14.189, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -17333,7 +17386,7 @@ query-string@^6.13.8: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" -query-string@^7.0.0: +query-string@^7.0.0, query-string@^7.0.1: version "7.1.3" resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== @@ -20277,6 +20330,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +url-join@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== + url-parse@^1.5.3, url-parse@^1.5.8: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" @@ -20285,6 +20343,11 @@ url-parse@^1.5.3, url-parse@^1.5.8: querystringify "^2.1.1" requires-port "^1.0.0" +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + integrity sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw== + url@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" From 9668333479f385e63a5100ee98da8c5ae8929eb4 Mon Sep 17 00:00:00 2001 From: Patrick Knight Date: Fri, 27 Jan 2023 16:51:20 -0500 Subject: [PATCH 3/4] Fix formatting issues --- packages/app/src/App.tsx | 4 +++- packages/backend/src/plugins/auth.ts | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index a34f747329..1ad60468fe 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -53,7 +53,9 @@ const app = createApp({ }); }, components: { - SignInPage: (props) => , + SignInPage: props => ( + + ), }, }); diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts index d6cf41c664..7b699124fd 100644 --- a/packages/backend/src/plugins/auth.ts +++ b/packages/backend/src/plugins/auth.ts @@ -5,7 +5,10 @@ import { } from '@backstage/plugin-auth-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; -import { DEFAULT_NAMESPACE, stringifyEntityRef } from '@backstage/catalog-model'; +import { + DEFAULT_NAMESPACE, + stringifyEntityRef, +} from '@backstage/catalog-model'; export default async function createPlugin( env: PluginEnvironment, @@ -54,7 +57,7 @@ export default async function createPlugin( signIn: { async resolver({ result }, ctx) { const name = result.getHeader('x-forwarded-preferred-username'); - if(!name) { + if (!name) { throw new Error('Request did not contain a user'); } From 0196e7a6e16085cd3a99ed24d896ecf63652cf33 Mon Sep 17 00:00:00 2001 From: Patrick Knight Date: Wed, 1 Feb 2023 08:55:35 -0500 Subject: [PATCH 4/4] Add Keycloak documentation --- docs/keycloak-plugin.md | 190 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 docs/keycloak-plugin.md diff --git a/docs/keycloak-plugin.md b/docs/keycloak-plugin.md new file mode 100644 index 0000000000..ad61c07c79 --- /dev/null +++ b/docs/keycloak-plugin.md @@ -0,0 +1,190 @@ +# Setting up to use the Keycloak plugin + +The Keycloak plugin allows you to view information about users and groups that were created in Keycloak within the Backstage app. This showcase application adds the Keycloak plugin to demonstrate the value that this plugin can provide. + +## Getting Started + +There will need to be an instance of Keycloak running within an OpenShift cluster. + +Create a new project called keycloak. +`oc new-project keycloak` + +Run Keycloak + +```shell +oc process -f https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/openshift-examples/keycloak.yaml \ + -p KEYCLOAK_ADMIN=admin \ + -p KEYCLOAK_ADMIN_PASSWORD=admin \ + -p NAMESPACE=keycloak \ + | oc create -f - +``` + +This will spin up a simple Keycloak server in the keycloak project namespace. The admin username and password are both set to admin. + +## Login into Keycloak + +The next steps will involve setting up users and preparing Keycloak to be used with the Backstage Showcase app. Start by opening up the Keycloak console and logging in using the admin credentials. + +### Create the Realm + +1. Select the drop down that says master and click on Create Realm +2. Fill in the Realm name portion of the form with the value backstage +3. Click Create + +### Create the Client + +1. Select the Clients option in the navigation bar +2. Select Create client button +3. Fill in the ID of the Client with backstage +4. Click next +5. Ensure the Client authentication and Service accounts roles are enabled +6. Click Save to create the client +7. Under the Service accounts roles, click the Assign role button +8. Filtering by clients and search with realm-management, select the query-groups, query-users, and view users options +9. Click Assign + +Under the Credentials tab we will find the Client secret that will be needed later on in the guide. + +### Create the Groups + +1. Select the Groups option in the navigation bar +2. Select the Create group button +3. Create the groups Admins and Users + +### Create the Users + +1. Select the Users option in the navigation bar +2. Input the information based on the chart below to create the users + +| Property | User 1 | User 2 | +| -------------- | --------------------------- | -------------------------- | +| Username | backstageadmin | backstageuser | +| Email | backstageadmin@janus-idp.io | backstageuser@janus-idp.io | +| Email Verified | Checked | Checked | +| First Name | Backstage | Backstage | +| Last Name | Admin | User | +| Groups | Admins | Users | + +3. After the accounts have been created, click on the Credentials tab to Set a Password + +- Ensure to uncheck the temporary option + +### Endpoint + +1. Navigate to the Realm setting using the option in the navigation bar +2. Click on the OpenID Endpoint Configuration link + +Here you will find the issuer URL that will be needed later in this guide. + +## Deploying to a Kubernetes cluster + +This guide will have a focus on deploying to an OpenShift cluster as that is the main target for this project. + +Utilizing the same values-backstage-showcase.yaml file, we will make some changes to integrate Keycloak into the app. + +```yaml +backstage: + image: + registry: + repository: + tag: + extraEnvVars: + # Base environment variables + - name: 'APP_CONFIG_app_baseUrl' + value: 'https://{{ .Values.ingress.host }}' + - name: 'APP_CONFIG_backend_baseUrl' + value: 'https://{{ .Values.ingress.host }}' + - name: 'APP_CONFIG_backend_cors_origin' + value: 'https://{{ .Values.ingress.host }}' + + # Keycloak environment variables + - name: "APP_CONFIG_catalog_providers_keycloakOrg_default_baseUrl" + value: '{{ required "Keycloak BaseUrl is Required" .Values.catalog.providers.keycloakOrg.default.baseUrl }}' + - name: "APP_CONFIG_catalog_providers_keycloakOrg_default_loginRealm" + value: '{{ required "Keycloak Login Realm is Required" .Values.catalog.providers.keycloakOrg.default.realm }}' + - name: "APP_CONFIG_catalog_providers_keycloakOrg_default_realm" + value: '{{ required "Keycloak Realm is Required" .Values.catalog.providers.keycloakOrg.default.realm }}' + - name: "APP_CONFIG_catalog_providers_keycloakOrg_default_clientId" + value: '{{ required "Keycloak Client Id is Required" .Values.catalog.providers.keycloakOrg.default.clientId }}' + - name: "APP_CONFIG_catalog_providers_keycloakOrg_default_clientSecret" + value: '{{ required "Keycloak Client Secret is Required" .Values.catalog.providers.keycloakOrg.default.clientSecret }}' + + extraContainers: + - name: oauth2-proxy + env: + - name: OAUTH2_PROXY_CLIENT_ID + value: '{{ required "Keycloak Client Secret is Required" .Values.keycloak.clientId }}' + - name: OAUTH2_PROXY_CLIENT_SECRET + value: '{{ required "Keycloak Client Secret is Required" .Values.keycloak.clientSecret }}' + - name: OAUTH2_PROXY_COOKIE_SECRET + value: '{{ default (randAlpha 32 | lower | b64enc) .Values.keycloak.cookieSecret }}' + - name: OAUTH2_PROXY_OIDC_ISSUER_URL + value: '{{ required "Keycloak Issuer URL is Required" .Values.keycloak.issuerUrl }}' + - name: OAUTH2_PROXY_SSL_INSECURE_SKIP_VERIFY + value: 'true' + ports: + - name: oauth2-proxy + containerPort: 4180 + protocol: TCP + imagePullPolicy: IfNotPresent + image: 'quay.io/oauth2-proxy/oauth2-proxy:latest' + args: + - '--provider=oidc' + - '--email-domain=*' + - '--upstream=http://localhost:7007' + - '--http-address=0.0.0.0:4180' + - '--skip-provider-button' + +service: + ports: + backend: 4180 + targetPort: oauth2-proxy + +ingress: + enabled: true + host: backstage. + +keycloak: + issuerUrl: + clientId: backstage + clientSecret: + cookieSecret: '' + +catalog: + providers: + keycloakOrg: + default: + baseUrl: + loginRealm: backstage + realm: backstage + clientId: + clientSecret: +``` + +The domain can be found using the following command. + +```shell +oc describe ingresscontroller/default -n openshift-ingress-operator | grep Domain: +``` + +The `` can be found from the Realm settings page. + +`` is the portion of the endpoint issuer url minus the `/realms/backstage`. + +`` can be found under the credentials tab of the client that you created and `` is the name of the client you created. + +Next, using Helm, we will deploy the Backstage Showcase app to OpenShift using the following command. + +```shell +helm install -n backstage --create-backstage backstage/backstage -f values-backstage-showcase.yaml +``` + +When navigating to your instance of the Backstage Showcase app, Oauth2 proxy will intercept the request and redirect to the Keycloak login. Now we can log in using either of the two users previously created. + +Finally, we will navigate to the Catalog page using the Home option in the navigation bar. From here, we can choose to filter by users from the dropdown to see the two users that we originally created from within Keycloak. + +## For more information + +More information on the Keycloak plugin can be found on in the Janus IDP [backstage-plugins](https://github.com/janus-idp/backstage-plugins/tree/main/plugins/keycloak-backend) repository. + +There is also a Janus IDP blog post [Enabling Keycloak Authentication in Backstage](https://janus-idp.io/blog/enabling-keycloak-authentication-in-backstage).