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.
On April 29, you’re invited to join Levvel experts and Rob Galbraith, Bestselling Author at Insurance Nerds, for a webinar on how to best prepare and support a technology approach that meets evolving insured’s expectations.
Webinar
Apr 29
In this new video series from Levvel, our industry experts discuss where organizations should start if embarking on their first migration journey, ways to get unstuck, and how to gain buy-in when faced with internal resistance.
Blog
Apr 07
This article provides insight into the legacy architecture challenges national insurers face and their impact on reaching business goals.
Blog
Mar 06
In this new video series, our industry experts discuss why organizations struggle to adopt the cloud, ways to determine which cloud strategy is the right path for your business, and industry best practices when embarking on a cloud migration journey.
Blog
Mar 04