OpenID Connect (Authorization Code Flow) with Red Hat SSO

This post was originally published as “White Paper: OpenID Connect (Authorization Code Flow) with Red Hat SSO” on the Levvel Blog.

Patterns on the wall. / John

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:

  • Keep things simple

OIDC can integrate with:

  • Traditional web applications

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.

Assumptions:

Let’s start with some assumptions to make sure we are all on the same page.

  • This document assumes basic familiarity with Red Hat SSO.

Red Hat SSO Instance Installation

Follow the instructions here to install Red Hat SSO v7.1. The installation details are outside the scope of this blog post.

Red Hat SSO Realm Setup Procedure

  • Enter a username and password with admin privileges.
  • Mouse over the “Select realm” drop down.
  • Add the name “blog_demo”.
  • Make note of the OIDC endpoints by clicking on the OpenID Connect Endpoint configuration link in the Endpoints field. We’ll need several of these values later. For the blog_demo realm, we have:
{
"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
}
  • Click on the Keys tab.
  • Click the Providers tab.
  • Click the drop down.
  • Change the “Console Display Name” to “blog-post-rsa-key-pair”.
  • Click the Delete link next to the rsa-generated key pair.
  • Click the Delete button.
  • Note, if your organization has a key pair (with certificate issued out of an internal CA) that should be used for signing tokens, then that be uploaded using a similar set of steps.
  • Change the Access Token Lifespan to 60 minutes. The actual value used for a production application will depend on several factors. We are using 60 minutes here so that things do not timeout while completing the tutorial.

Setup Red Hat SSO Client Configuration

  • Click the Clients link in the left-hand column.
  • Click the Create button.
  • Set the Client ID to “blog-post-demo-client-001”.
  • Set Consent Required to Off. We are not going to deal with user consent in this simple example — that will come later.
  • Scroll down to the Web Origins field at the bottom of the Settings tab.
  • Click the Credentials tab.
  • Make note of the Secret value (this is the client secret).
  • Click the “Add Role” button.

Create The Test User

  • Put “User” in the Role Name.
  • Click on the Users link on the left-hand column.
  • Click the “Add user” button.
  • Add user1 to the Username field.
  • Click on the Credentials tab.
  • Add a password for this user to the “New Password” field (maybe, “password123”).
  • Click “Change Password”.

Create The Test Group

  • Click on the Groups link on the left-hand column.
  • Click the New button.
  • Enter Group1 in the name field.
  • Click the Role Mappings tab.
  • In the Client Roles drop down, choose “blog-post-demo-client-001”.
  • Select the User role from the “Available Roles” field.
  • Click on the Members tab.
  • Go back to the users section.
  • Click on the link for the user1 user.
  • Click on the Groups tab.
  • Select Group1 from the Available Groups list.
  • If you are following these instructions for another blog posts, you can stop here.

Test User Login with OpenID Connect

  • Follow the instructions here to setup the OAuth2 + OIDC Debugger app on your local machine. This is a simple test application that simulates the interaction between a real app and an IdP using the OAuth2 or OIDC protocols.
  • Choose “OIDC Authorization Code Flow.
  • Populate the Authorization Endpoint field with the URL from the meta data document we captured earlier (authorization_endpoint attribute).
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&
scope=openid profile User
  • Red Hat SSO will prompt for credentials if there isn’t already an authenticated session.
  • Enter the username (User1) in the “Username or email” field.
  • Put the client identifier in the Client ID field (use “blog-post-demo-client-001”).
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&
scope=openid profile User
  • This will return a response with the access token, ID Token, refresh token, and other attributes.
  • This response from the IdP looks similar to the following (note, the tokens shown below have been corrupted so that you cannot see the original contents):
{
"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"
}
  • The OAuth2 access token is stored in the access_token attribute. This is a JWT token. The JWT payload contains:
{
"jti": "2797c97a-ca33-4313-b5ed-4675123c1b98",
"exp": 1510365618,
"nbf": 0,
"iat": 1510365318,
"iss": "https://ipd.levvel.io/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"
],
"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
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:

  • CLIENT_ID

In future blog posts, 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.

Image: Patterns on the wall. / John

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Robert Broeckelmann

My focus within Information Technology is API Management, Integration, and Identity–especially where these three intersect.