White Paper
January 31, 2018
In this post, we are going to configure Red Hat SSO v7.1 for OpenID Connect (OIDC) with the Authorization Code Authentication Flow and demonstrate usage with a simple test application. Later, we are going to use this configuration as the basis for more sophisticated examples using 3Scale API Management.
OpenID Connect (and OAuth2) has emerged as the de facto standard for API, mobile applications, and modern Single Page Application (SPA) authentication and single sign-on, but it is flexible enough to be used in many other contexts. A typical use case for OIDC would be a SPA or mobile application that needs to authenticate an end user and then make API calls that also require authentication.
I’ve covered the details of the OIDC spec (and related specs) in a previous post, but let’s review the basic idea. From openid.net, “OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.” This “REST-like manner” makes OIDC more like an API (in line with OAuth2) than the previous generations of OpenID. OIDC extends the OAuth2 Authorization Code Grant (three-legged OAuth).
OIDC builds on the lessons of the early OpenID protocols and SAML2 including:
OIDC can integrate with:
Each of these application types have a corresponding authentication flow in the OIDC spec that is meant to be used. There is some overlap; as always, there is some gray area (checkout this blog post regarding which OAuth2 Implicit Grant should be used). Not every vendor uses the same authentication flows to satisfy each use case. At the end of the day, you have to work within the boundaries set by your Identity Provider vendor.
Let’s start with some assumptions to make sure we are all on the same page.
Follow the instructions here to install Red Hat SSO v7.1. The installation details are outside the scope of this blog post.
{
"issuer": "https://idp.levvel.io:8443/auth/realms/blog_demo",
"authorization_endpoint": "https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/auth",
"token_endpoint": "https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/token",
"token_introspection_endpoint": "https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/userinfo",
"end_session_endpoint": "https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/logout",
"jwks_uri": "https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/certs",
"check_session_iframe": "https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/login-status-iframe.html",
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"password",
"client_credentials"
],
"response_types_supported": [
"code",
"none",
"id_token",
"token",
"id_token token",
"code id_token",
"code token",
"code id_token token"
],
"subject_types_supported": [
"public",
"pairwise"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"userinfo_signing_alg_values_supported": [
"RS256"
],
"request_object_signing_alg_values_supported": [
"none",
"RS256"
],
"response_modes_supported": [
"query",
"fragment",
"form_post"
],
"registration_endpoint": "https://idp.levvel.io:8443/auth/realms/blog_demo/clients-registrations/openid-connect",
"token_endpoint_auth_methods_supported": [
"private_key_jwt",
"client_secret_basic",
"client_secret_post"
],
"token_endpoint_auth_signing_alg_values_supported": [
"RS256"
],
"claims_supported": [
"sub",
"iss",
"auth_time",
"name",
"given_name",
"family_name",
"preferred_username",
"email"
],
"claim_types_supported": [
"normal"
],
"claims_parameter_supported": false,
"scopes_supported": [
"openid",
"offline_access"
],
"request_parameter_supported": true,
"request_uri_parameter_supported": true
}
GET https://idp.levvel.io/auth/realms/demo_project_sf/protocol/openid-connect/auth?
state=38610846-c64d-4fd2-8d9-b5fa2f976298&
response_type=code&
client_id=blog-post-demo-client-001&
redirect_uri=[http://localhost:3000/callback&](http://localhost:3000/callback&)
scope=openid profile User
POST https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect/token?
grant_type=authorization_code&
code=XGflSf5kFIpAE_VNBcbGqH9D030qOeuU2yw5kiBAPcg.6df35f39-bbc5-4eb3-bf92-79e94644b957&
client_id=blog-post-demo-client-001&
redirect_uri=[http://localhost:3000/callback&](http://localhost:3000/callback&)
scope=openid profile User
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOixAiSldUIiwia2lkIiA6ICJlbxng0N0FqcFdVRHhBWjRidkl4RFJGMXBlSnpPNnZpa0JvUW8x5U2MzYVVRIn0.eyJqdGkiOiIyNzk3Yzk3YS1jYTsMzLTQzxMdTMxtYjVlxZC00xNjcx1M4fTIzYzFiOTgiLCJleHAiOxjE1MTAzNjU2MTgsIm5iZiI6MCwxiaWF0IjoxNTEwMzY1MzE4LCJpc3MiOiJodHRwczovL2VjMi01Mi03Mi03MS0yMjkxuY29tcHV0ZS0xLmFtYXpvbmF3cy5jb206xODQ0My9hdXRoL3JlYWxtcy9ibG9nX2RlbW8iLCJhd6WQixOiJibG9nLXBvc3QtZGVtby1jbGllbn0QtMDAxIiwic3ViIjoxiNzFjOTA0ZjEtZTk3O8C00NTQyLTgwZGUtZmE5OGViYjI0MWU1IiwidHlwIjoiQmVhcmVyIxiwiYXpwIjoiYmxvZy1wb3N0LWRlbW8tY2xpZW50LTAwMSIsIm5vbmNlIjoiMWVmODdlZGMtNzZkYy00YWYzLWJmMmYtNWEzNzJjZTA2YmUyIiwiYXV0aF90aW1lIjoxNTEwMzYxMTYxLCJzZXNzaW9uX3N0YXRlIjoiYjY3M2M4M2YtYTY3Mi00M2YxLWFkMWItNjI2OG5E5N2M5MDMwIiwiYWNyIjoiMCIsIm987896NsaWVudF9zZXNzaW9uIjoiNTBmZWM2YWEtMzMyZS00MmU0LWFiM2UtMzE0YTU2NGJjYTBiIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiLCJodHRwOi8vbG9jYWxob3N0OjMwMDAiXSwicmVzb3VyY2VfYWNjZXNzIjp7ImJsb2ctcG9zdC1kZW1vLWNsaWVudC0wMDEiOnsicm9sZXMiOlsiVXNlciJdfX0sIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ1c2VyMSJ9.AYvnrPJ615eMNEWcr3zjD0auPgYr6ZsmYw1JR___0sTNW9YL3YyatEUttPAiJZNsr15s93xBp40svbv_GlZgsG57FZaYF0PNH79nbd8EzcrA_-M6vVED1mLQR9rd96Ec8ISCzEQhYcESBmOjI1ZZ2cFP05Uw1AfLI1CXWT9ExTbKknnahIYVLOeFJ2n9xr7JYgolBfeE4VksIktEk0hlUQf762nQ8uwZ4ycGBfHAZkLfvTodyQT5T3ulpNMg0_SSQDGmACKrq9YhG8wshw2PWWTjAMfnARvM5NiPCxGaf3qnFFz5bWjMbbDAyVKRmRYl1S8rJ2q1WBK9HkFH5fHIzng",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlbng0N0FqcFdVRHhBWjRidkl4RFJGMXBlSnpPNnZpa0JvUW85U2MzYVVRIn0.eyJqdGkiOiI4MWRjNGQ4NS1hMzdhLTRkZxmEtxOGNxiOC0zMxGE3OxDNiNDIxYzIiLCJleHAiOjE1MTAzNjcxMTxgsImx5ixZiI6MCxwiaWF0xIjoxNTEwMzY1MzE4LCJpc3MiOixJodHRxwczovL2VjxMi01Mix03Mi03MS0yMjkuY29tcHV0ZS0xLmFtYXpxvbmF3cy5jxb206ODQ0My9hdXRoL3JlYWxtcy9ibG9nX2RlbW8iLCJhdWQiOiJibG9xxnLXBvc3QtZGVtby1jbGllbnQtMDAxIiwic3ViIjoiNzFjOTA0ZjEtZTk3OC00NTQyLTgwZGUtZmE5OGViYjI0MWU1IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImJsb2ctcG9zdC1kZW1vLWNsaWVudC0wMDEiLCJub25jZSI6IjFlZjg3ZWRjLTc2ZGMtNGFmMy1iZjJmLTVhMzcyY2UwNmJlMiIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6ImI2NzNjODNmLWE2NzItNDNmMS1hZDFiLTYyNjhhOTdjOTAzMCIsImNsaWVudF9zZXNzaW9uIjoiNTBmZWM2YWEtMzMyZS00MmU0LWFiM2UtMzE0YTU2NGJjYTBiIiwicmVzb3VyY2VfYWNjZXNzIjp7ImJsb2ctcG9zdC1kZW1vLWNsaWVudC0wMDEiOnsicm9sZXMiOlsiVXNlciJdfX19.PlZuB-TY_UasHdW-bEhC-uZQpTtm3-Jdnw5Gh5FIE8q6d3iAyUWyjHLrhL80z71XO8M8oeCW3Zjzd8QCPDbSyPJSiSCcDwgIRV7m0FKQJI-F7kBroYR-ADYi6SULl1Ul8PrOI0repgcLCVeaAkM07uXuIE2popMTbQzP1eZk7zjO0MvjUtBkk7UH-aAGV-75KarU0JQMLnKpu-DAp3A8fPmbgjLTu1eajj7DqAkcwJZWm7CefTzM3Kl5BRt4HiDcEsSbJfSVtPnlwmUoClholzu5-vgf7_5a8O-Alqn_SnRXuXkaaIRSL1ZZVCER-HuTLYWJFtRlXfbIbuiiktgAQg",
"token_type": "bearer",
"id_token": "eyJhbGciOiJSxUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlbng0N0FqcFdVRHhBWjRidkl4RFxJGMXBlSnpPNxnZpax0JvUWx85U2MzYVxVRInx0.eyJqdxGkiOiJiZmFlMx2M2OS1xiYzkxLxTQ5Y2IxtODM2Yi0zZxDNmMjJkYjxFhYzxMiLCJlxeHAiOjE1MxTxAzNjU2xMTgsIm5ixZiI6MCwiaxWF0IjoxNTExwMzY1MzEx4LCJpc3MiOiJodHRwczovL2VjMi01Mi03Mi03MS0yMjkuY29tcHV0ZS0xLmFtYXpvbmF3cy5jb206ODQ0My9hdXRoL3JlYWxtcy9ibG9nX2RlbW8iLCJhdWQiOiJibG9nLXBvc3QtZGVtby1jbGllbnQtMDAxIiwic3ViIjoiNzFjOTA0ZjEtZTk3OC00NTQyLTgwZGUtZmE5OGViYjI0MWU1IiwidHlwIjoiSUQiLCJhenAiOiJibG9nLXBvc3QtZGVtby1jbGllbnQtMDAxIiwibm9uY2UiOiIxZWY4N2VkYy03NmRjLTRhZjMtYmYyZi01YTM3MmNlMDZiZTIiLCJhdXRoX3RpbWUiOjE1MTAzNjExNjEsInNlc3Npb25fc3RhdGUiOiJiNjczYzgzZi1hNjcyLTQzZjEtYWQxYi02MjY4YTk3YzkwMzAiLCJhY3IiOiIwIiwibmFtZSI6IiIsInByZWZlcnJlZF91c2VybmFtZSI6InVzZXIxIn0.MnryJ_SXqi0FEZo5cfVEhsg8pLVy1nBrrtxud3bP7XWpINSkY6n6xQycWvOxhEBga2x82RM4qB6mcprgJm3LsBitjrV4X24AJyv1v2sBp1xX0skgKVLyD70UTFRhL9q-koJTu4CMCIich-wmFnhrRnzUujafLVL61LVS41keVfScRdOofDHoAZBXicwhHIi5SM9Poo16EIsHgh31_i9AKsX7gkaZskgx_erJe1ArAmxxVf23LPkYpcQM-4R6aEN_jZ9JQowHZmLbj7zltvbATApTFMQ6SoswhtnA8bVezT3P-PC2didkeSNzTyKYhyUviuN1fASm7T2zj58ZCy-b2Q",
"not-before-policy": 0,
"session_state": "b673c83f-a672-43f1-ad1b-6268a97c9030"
}
{
"jti": "2797c97a-ca33-4313-b5ed-4675123c1b98",
"exp": 1510365618,
"nbf": 0,
"iat": 1510365318,
"iss": "[https://ipd.levvel.io/auth/realms/blog_demo](https://ec2-52-72-71-229.compute-1.amazonaws.com:8443/auth/realms/blog_demo)",
"aud": "blog-post-demo-client-001",
"sub": "71c904f1-e978-4542-80de-fa98ebb241e5",
"typ": "Bearer",
"azp": "blog-post-demo-client-001",
"nonce": "1ef87edc-76dc-4af3-bf2f-5a372ce06be2",
"auth_time": 1510361161,
"session_state": "b673c83f-a672-43f1-ad1b-6268a97c9030",
"acr": "0",
"client_session": "50fec6aa-332e-42e4-ab3e-314a564bca0b",
"allowed-origins": [
"*",
"[http://localhost:3000](http://localhost:3000/)"
],
"resource_access": {
"blog-post-demo-client-001": {
"roles": [
"User"
]
}
},
"name": "",
"preferred_username": "user1"
}
You can see that the JWT token describes a user called “user1” and that it is a member of the User role.
An alternative testing mechanism is to run the following shell script that simulates at the calls made to the IdP for the Authorization Code Flow.
#!/bin/bash
#set -x
STATE=`uuidgen`
CLIENT_ID=MY_CLIENT_ID
CLIENT_SECRET=MY_CLIENT_SECRET
FINAL_REDIRECT_URI=[http://localhost:3000/callback](http://localhost:3000/callback)
USERNAME_=MY_USERNAME
PASSWORD_=MY_PASSWORD
IDP_BASE_URL=https://idp.levvel.io:8443/auth/realms/blog_demo/protocol/openid-connect
CURL_OUTPUT=`curl -X GET "${IDP_BASE_URL}/auth?client_id=${CLIENT_ID}&response_type=code&scope=openid%20profile%20email&state=${STATE}&redirect_uri=${FINAL_REDIRECT_URI}" --insecure -D headers.out`
echo CURL_OUTPUT=${CURL_OUTPUT}
PASSWORD_SUBMIT_URL=`echo $CURL_OUTPUT | awk '{print $100 }' |
cut -c 8- | sed 's/"//g'`
echo PASSWORD_SUBMIT_URL=${PASSWORD_SUBMIT_URL}
CURL_OUTPUT=`curl -X POST "${PASSWORD_SUBMIT_URL}" -d "username=${USERNAME_}&password=${PASSWORD_}" --insecure -D /var/tmp/headers.out`
echo CURL_OUTPUT=$CURL_OUTPUT
echo /var/tmp/headers.out
REDIRECT_URL=`cat /var/tmp/headers.out | grep ^Location | cut -c10-`
echo $REDIRECT_URL
CODE=`echo $REDIRECT_URL | awk -F"?" '{ print $2 }' | awk -F"&" '{print $2}' | awk -F"=" '{print $2}' | sed 's/r//g'`
echo CODE=$CODE
CURL_OUTPUT=`curl -X POST "${IDP_BASE_URL}/token" -d "state=${STATE}&code=${CODE}&grant_type=authorization_code&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&redirect_uri=${FINAL_REDIRECT_URI}" --insecure -D headers.out`
echo CURL_OUTPUT=${CURL_OUTPUT}
ACCESS_TOKEN=`echo ${CURL_OUTPUT} | python -c "import sys, json; print json.load(sys.stdin)['access_token']"`
echo "-------------------------------------"
echo ACCESS_TOKEN=${ACCESS_TOKEN}
echo "-------------------------------------"
ID_TOKEN=`echo ${CURL_OUTPUT} | python -c "import sys, json; print json.load(sys.stdin)['id_token']"`
echo "-------------------------------------"
echo ID_TOKEN=${ID_TOKEN}
echo "-------------------------------------"
REFRESH_TOKEN=`echo ${CURL_OUTPUT} | python -c "import sys, json; print json.load(sys.stdin)['refresh_token']"`
echo "-------------------------------------"
echo REFRESH_TOKEN=${REFRESH_TOKEN}
echo "-------------------------------------"
The output of this script will look something like:
-------------------------------------
ACCESS_TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlbng0N0FqcFdVRHhBWjRidkl4RFJGMXBlSnpPNnZpa0JvUW85U2MzYVVRIn0.eyJxqdGkiOxiIzMzxJlMGY1Zi04NxDgxLTQxZDAxtYTRxmZi02ZxDRiZjgyMxmFkNDcixLCJleHAiOjxE1MTAwMzxM2MjgsImx5iZiI6MCxwiaWF0IjoxNxTEwMDMxzMzI4LCJpc3MiOiJodHRwczovL2VjMi01Mi03Mi03MS0yMjkuY29tcHV0ZS0xLmFtYXpvbmF3cy5jb206ODQ0My9hdXRoL3JlYWxtcy9ibG9nX2RlbW8iLCJhdWQiOiJibG9nLXBvc3QtZGVtby1jbGllbnQtMDAxIiwic3ViIjoiNzFjOTA0ZjEtZTk3OC00NTQyLTgwZGUtZmE5OGViYjI0MWU1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYmxvZy1wb3N0LWRlbW8tY2xpZW50LTAwMSIsImF1dGhfdGltZSI6MTUxMDAzMzMyNywic2Vzc2lvbl9zdGF0ZSI6ImU2MmI1NDIyLTY5YTMtNGFjZC04MDU5LTJjNTIxNWU0NmJlZCIsImFjciI6IjEiLCJjbGllbnRfc2Vzc2lvbiI6IjQyODQzNGUzLTllNzItNGM1Ny05YTQ4LTFlMWMxNmZkNWI2YyIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX19LCJuYW1lIjoiIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidXNlcjEifQ.dfjXZrNOb0oyoI6FoMxPmjiLAfI2orzOD0zeTA29z4C8cSoOifKnkL5clbFP_kk1ejHEnmFn17OIxx1_s5m6lRmLXHq6u6ZhSnjYCqvLwbDfszaiZzcJ_UbJagnJ_QfuIwlEdnRJj9C6Ne-ZEm8WwCLDidyDNyA6LufaKUVyFgPs4A4pYOy28YhU8sIBgOgjkmbR5lFK07Z0Uj3bsPFEJOu51E7VWgbIQQPlQFa95Hmw8BSHVcJRytj3gmBSHlavLh232jR2D0GyHzphmi2hgw4UBdHIx23H2bJUUbD7XXGxPENHazrx5U1xo_ojkJXlS1et158P66mr9wTzMnZULw
-------------------------------------
-------------------------------------
ID_TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlbng0N0FqcFdVRHhBWjRidkl4RFJGMXBlSnpPNnZpa0JvUW85U2MzYVVRIn0.eyJqxdGkixOiIwZGU4MxDc1Mi1hZTxdmLTRkODMtYxjI2Zi02NjxU0YmE4Y2UxwNDQiLCJleHxAiOjE1MTAxwMzM2MxjgsIm5iZiIx6MCwiaWF0IxjoxNTEwMDMxzMzI4LCJpc3xMiOiJodHRwxczovL2VjxMi01Mi03xMi03MS0yMxjkuY29tcHxV0ZS0xLxmxFtYXpvbmF3cy5jb206ODQ0My9hdXRoL3JlYWxtcy9ibG9nX2RlbW8iLCJhdWQiOiJibG9nLXBvc3QtZGVtby1jbGllbnQtMDAxIiwic3ViIjoiNzFjOTA0ZjEtZTk3OC00NTQyLTgwZGUtZmE5OGViYjI0MWU1IiwidHlwIjoiSUQiLCJhenAiOiJibG9nLXBvc3QtZGVtby1jbGllbnQtMDAxIiwiYXV0aF90aW1lIjoxNTEwMDMzMzI3LCJzZXNzaW9uX3N0YXRlIjoiZTYyYjU0MjItNjlhMy00YWNkLTgwNTktMmM1MjE1ZTQ2YmVkIiwiYWNyIjoiMSIsIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ1c2VyMSJ9.NWc9-smsugo74-3cDi_zl9-rEo508vt-IubuFYbPj4I1txwrKEVtuqqLbanQGIFJ5DH1bFfGsegZZV4KBoojTlN5ZHVfM--Van5wKFPFaeElUwE6RFtTQIe7kIIPeCNWtbaqpKc85yojs7vUyGXKJzpV52C8U5-4Dr9w4BrhGkIUgIw3ptblbciT2mwGm4ssyqGlx_6G30dBE-PCLWQYw7bkFVgniJNqS_1f0CLH5_XpHGM34ek71XAbSFeiN1zUEMAe_pHZZ_TJRD6p-fRiWpsJyBSoMSbWCtK6-_h2cymRJ3YvRlXFnyN3UKsRUjOAWs8KO4shoDfM7Ke26n9agw
-------------------------------------
-------------------------------------
REFRESH_TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlbng0N0FqcFdVRHhBWjRidkl4RFJGMXBlSnpPNnZpa0JvUW85U2MzYVVRIn0.eyJqxdxGkiOixIyOWUzMTYzxZC1kOWM4xLTQ3OWYtODUyxMC01OWVhxOWIzN2VkxM2UiLCJxleHAiOjE1xMTAwMzUxMxjgsIm5iZiIx6MCwiaWF0IxjoxNTEwMDxMzMzI4LCxJpc3MiOxiJodHRxwczovL2VjMix01Mi03Mi03MSx0yMjkuY2x9tcHV0ZS0xxLmFtYXpvxbmF3cy5jb2x06ODQ0My9hxdXRoL3JlYWxxtcy9ibGx9nX2RlbWx8xiLCJhdWQiOiJibG9nLXBvc3QtZGVtby1jbGllbnQtMDAxIiwic3ViIjoiNzFjOTA0ZjEtZTk3OC00NTQyLTgwZGUtZmE5OGViYjI0MWU1IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImJsb2ctcG9zdC1kZW1vLWNsaWVudC0wMDEiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJlNjJiNTQyMi02OWEzLTRhY2QtODA1OS0yYzUyMTVlNDZiZWQiLCJjbGllbnRfc2Vzc2lvbiI6IjQyODQzNGUzLTllNzItNGM1Ny05YTQ4LTFlMWMxNmZkNWI2YyIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX19fQ.LiiPu5jy5a3Y1wkdtKkm0Pp2D7llHeCpE6cAArbp5dWutqhcaGeVAs0eOgCx-IrfqHwZGY1bYdkTa0a2EB-MH8gJCYMZ3xqVeJ9yNaqBjrlM0bJwLT7pvf8kni1R6fsI3odOCS7S_Cy8Haj80EbQ6Zxmw8h5TGL6ZGiXVJPOzzMmuFLA7S02YPqKf9sXHqDy5lHbkSIUGSxCU2kLNUkxzwCfeN7_vYbX9AH2ygoYm3y2fCjV7er9qLwL5Can3JBCfeqF0a7H-KOP1BYXrBk-eEZp8K5bCx1PChx6OlwVKpE3H3FcZeeRLKOFelGT-GgGdNTSrF3UOIUJbD-gbpjHCw
-------------------------------------
You can customize this script to work with your IdP and client by updating:
In a future white paper, we’ll look at the other OAuth2 Grants and OIDC flows that are supported by Red Hat SSO, integration with 3Scale, and explore the RH SSO implementation details of the specs.
Authored By
Robert C. Broeckelmann Jr.
Meet our Experts
Let's chat.
You're doing big things, and big things come with big challenges. We're here to help.