Get OpenID Connect tokens from Keycloak

Published by Tobias Hofmann on

3 min read

After creating an OAuth 2.0 scope and client and assigning the scope to the client, we can test the configuration. To do this, we need to log on in Keycloak as the OAuth 2.0 client. Keycloak will then validate the client and provide the Access Tokens and the scope(s) assigned to the client.

I will use Postman to test the setup. The Postman requests can be found in my GitLab repository. The request is as following:

  • Type: POST
  • URL: http://localhost:8080/auth/realms/master/protocol/openid-connect/token
  • Header: Content-Type application/x-www-form-urlencoded
  • Body: grant_type=client_credentials&client_id=oidclient&client_secret=7bc40a29-3eba-4c01-a9f1-9ebbb2eb8e9c

To authenticate, you need to send the client_id and client secret. These are the same values as for the client in Keycloak.

client_id: oidclient
client_secret: 7bc40a29-3eba-4c01-a9f1-9ebbb2eb8e9c

The parameter grant_type informs Keycloak about the authentification type we want. Client_credentials means that we send the client secret, and together with the client id this authenticates the client. Make sure to protect the client secret! This also explains why HTTPS is a minimum requirement.

grant_type: client_credentials

Result

Keycloak returns the JWT, including the access and refresh token as well as the scope. The assigned scope ZDEMO_CDS_SALESORDERITEM_CDS_0001 is included, allowing the client to access resources that are assigned to that scope.

{
   "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIyeFlIOWNnTThaSzl2Rm1nSEN3QzFiMlRWQzdCZGNldWIyTjB0SGRjU3dZIn0.eyJqdGkiOiIzODM1ODk0My1jMDRmLTRhMTktOTVkMS0wMjY5YTYwNGUyYmUiLCJleHAiOjE1NzQzNDAwNDIsIm5iZiI6MCwiaWF0IjoxNTc0MzM2NDQyLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjBlMmQxMGIyLTQwOTMtNGUzNi1iMjJiLTQ0MTg4MTE5NjVjOCIsInR5cCI6IkJlYXJlciIsImF6cCI6Im9pZGNsaWVudCIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6Ijc2Y2QxOTY1LTFhYjgtNDM1ZC05NThiLWNiNDQxOGM1OWIwOCIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiWkRFTU9fQ0RTX1NBTEVTT1JERVJJVEVNX0NEU18wMDAxIHByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImNsaWVudEhvc3QiOiIxNzIuMTcuMC4xIiwiY2xpZW50SWQiOiJvaWRjbGllbnQiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzZXJ2aWNlLWFjY291bnQtb2lkY2xpZW50IiwiY2xpZW50QWRkcmVzcyI6IjE3Mi4xNy4wLjEiLCJlbWFpbCI6InNlcnZpY2UtYWNjb3VudC1vaWRjbGllbnRAcGxhY2Vob2xkZXIub3JnIn0.CTrO-XuNM0pxa3xrJNZqGTkPzd88_AcvVKtbG7dy6cMwg_n8f1P2k2afoQMG-sN6JQzQ-Ei_0OIGkXrV6TGWLZqBI3Tgu3NKDoLMWu1PS7N9YA1ubXJN_277L91usWzqmaE_9o5Q6ubenh319tyBL5JUqe5veEfv5WabzwsbPqbx7BfiTf3iE0_xEyWrdXCT64s60hGRSUZqC8Pgz2qLKArfDF_Bs_w20R7Cr50qHx3WJQNO-w_X2DiufmgKD5Cb8Ue8TlpA9o5F88ZKzce-GVplJKY8d35Wjr07DuDTVFQzSWsBSM0Oi0FKuBYGy4mfXjcz8g0tKtcplf2UFurqmA",
    "expires_in": 3600,
    "refresh_expires_in": 1800,
   "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJmZmI5NDQ5ZS02MGIxLTQyZTMtYmEwYy1iNjQ0NDc0MjZiNDQifQ.eyJqdGkiOiJkMDc2Yzk3NS04ODA0LTRhNDUtODE3NS1jMmYxZDJjYzExZjIiLCJleHAiOjE1NzQzMzgyNDIsIm5iZiI6MCwiaWF0IjoxNTc0MzM2NDQyLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjBlMmQxMGIyLTQwOTMtNGUzNi1iMjJiLTQ0MTg4MTE5NjVjOCIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJvaWRjbGllbnQiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI3NmNkMTk2NS0xYWI4LTQzNWQtOTU4Yi1jYjQ0MThjNTliMDgiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiWkRFTU9fQ0RTX1NBTEVTT1JERVJJVEVNX0NEU18wMDAxIHByb2ZpbGUgZW1haWwifQ.blSzmr6gHXIhHY2ikAEXDiBfVQ17eVJsiWFdly8Krkk",
    "token_type": "bearer",
    "not-before-policy": 0,
    "session_state": "76cd1965-1ab8-435d-958b-cb4418c59b08",
    "scope": "ZDEMO_CDS_SALESORDERITEM_CDS_0001 profile email"
}

The content is encoded. Using a site like jwt.io, the content of the tokens can be decoded. For the access token:

{
	"jti": "38358943-c04f-4a19-95d1-0269a604e2be",
	"exp": 1574240042,
	"nbf": 0,
	"iat": 1574136442,
	"iss": "http://localhost:8080/auth/realms/master",
	"aud": "account",
	"sub": "0e2d10b2-4093-4e36-b22b-4418811965c8",
	"typ": "Bearer",
	"azp": "oidclient",
	"auth_time": 0,
	"session_state": "76cd1965-1ab8-435d-958b-cb4418c59b08",
	"acr": "1",
	"realm_access": {
		"roles": [
			"offline_access",
			"uma_authorization"
		]
	},
	"resource_access": {
		"account": {
			"roles": [
				"manage-account",
				"manage-account-links",
				"view-profile"
			]
		}
	},
	"scope": "ZDEMO_CDS_SALESORDERITEM_CDS_0001 profile email",
	"email_verified": false,
	"clientHost": "168.192.0.1",
	"clientId": "oidclient",
	"preferred_username": "service-account-oidclient",
	"clientAddress": "172.17.0.1",
	"email": "service-account-oidclient@placeholder.org"
}
Let the world know

Tobias Hofmann

Doing stuff with SAP since 1998. Open, web, UX, cloud. I am not a Basis guy, but very knowledgeable about Basis stuff, as it's the foundation of everything I do (DevOps). Performance is king, and unit tests is something I actually do. Developing HTML5 apps when HTML5 wasn't around. HCP/SCP user since 2012, NetWeaver since 2002, ABAP since 1998.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.