Red Hat SSO v7.1 OAuth2 Client Credentials Grant

This post continues our exploration of OAuth2 Authorization Grants with Red Hat SSO v7.1. In previous posts, we looked at:

Here we are going to look at the last of the four grants, the Client Credentials Authorization Grant. This Authorization Grant does not support end user authentication; it just authenticates the client application with client identifier and client secret.

The theoretical treatment of the Client Credentials Grant was done in an earlier post.

Once again, we will be using the OAuth2 + OIDC Debugger application to test this Authorization Grant.

To test the Client Credentials Grant, do the following:

  • Configure Red Hat SSO v7.1 per the instructions provided in this post. Make sure that “Service Accounts Enabled” is set to on for the client (the instructions in the blog post call this out).
  • 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.
  • Open a browser tab and go to http://localhost:3000
  • Choose “OAuth2 Client Credential” from the drop-down menu under “Choose Authorization Grant”.


  • Enter your client’s client identifier in the Client ID field. If you followed the instructions verbatim, this will be “blog-post-demo-client-001”.
  • Enter your Client’s client secret in the Client Secret field. This will be unique to your environment.
  • Enter the Redirect URL (use http://localhost:3000/callback if you are using the instructions provided).
  • Enter “User” as the scope.
  • Click the “Get Token” button.


You will see that an access token, refresh token, and ID token were returned. An example of the JWT payload for each of these tokens is given below. The key difference between these tokens and the previous examples is that what is below describes a “service account” (a generic account defined within Red Hat SSO that maps to the client/application) rather than an end user identity.

ID token:

{
"jti": "c36fa809-8362-48f2-b3be-79a727921bba",
"exp": 1510596867,
"nbf": 0,
"iat": 1510593267,
"iss": "https://idp.levvel.io:8443/auth/realms/blog_demo",
"aud": "blog-post-demo-client-001",
"sub": "f7ceb206-ee74-42e3-a558-e891ae42f938",
"typ": "ID",
"azp": "blog-post-demo-client-001",
"auth_time": 0,
"session_state": "7f13ffaa-24d8-4e51-9de5-46e5f663ff6f",
"acr": "1",
"clientHost": "1.1.1.1",
"clientId": "blog-post-demo-client-001",
"name": "",
"preferred_username": "service-account-blog-post-demo-client-001",
"clientAddress": "1.1.1.1",
"email": "service-account-blog-post-demo-client-001@placeholder.org"
}

Access Token:

{
"jti": "6c3904ea-5978-4578-87f8-39433c81b3c6",
"exp": 1510596867,
"nbf": 0,
"iat": 1510593267,
"iss": "https://idp.levvel.io:8443/auth/realms/blog_demo",
"aud": "blog-post-demo-client-001",
"sub": "f7ceb206-ee74-42e3-a558-e891ae42f938",
"typ": "Bearer",
"azp": "blog-post-demo-client-001",
"auth_time": 0,
"session_state": "7f13ffaa-24d8-4e51-9de5-46e5f663ff6f",
"acr": "1",
"client_session": "ed61f06b-76d8-40b5-a966-b94c6422bd6c",
"allowed-origins": [
"*",
"http://localhost:3000"
],
"resource_access": {
"blog-post-demo-client-001": {
"roles": [
"User"
]
}
},
"clientHost": "1.1.1.1",
"clientId": "blog-post-demo-client-001",
"name": "",
"preferred_username": "service-account-blog-post-demo-client-001",
"clientAddress": "1.1.1.1",
"email": "service-account-blog-post-demo-client-001@placeholder.org"
}

Refresh Token:

{
"jti": "6c3904ea-5978-4578-87f8-39433c81b3c6",
"exp": 1510596867,
"nbf": 0,
"iat": 1510593267,
"iss": "https://idp.levvel.io:8443/auth/realms/blog_demo",
"aud": "blog-post-demo-client-001",
"sub": "f7ceb206-ee74-42e3-a558-e891ae42f938",
"typ": "Bearer",
"azp": "blog-post-demo-client-001",
"auth_time": 0,
"session_state": "7f13ffaa-24d8-4e51-9de5-46e5f663ff6f",
"acr": "1",
"client_session": "ed61f06b-76d8-40b5-a966-b94c6422bd6c",
"allowed-origins": [
"*",
"http://localhost:3000"
],
"resource_access": {
"blog-post-demo-client-001": {
"roles": [
"User"
]
}
},
"clientHost": "1.1.1.1",
"clientId": "blog-post-demo-client-001",
"name": "",
"preferred_username": "service-account-blog-post-demo-client-001",
"clientAddress": "1.1.1.1",
"email": "service-account-blog-post-demo-client-001@placeholder.org"
}

OAuth2 becoming widely supported allowed a standards-based mechanism to provide a concept of the application (client) to the Identity Provider. Before this, a generic user would be used by an application to connect to protected resources. How this application concept relates to a role is heavily implementation dependent. In this example, Red Hat SSO v7.1 Service Accounts can be members of roles just like end user identities — this is useful. I’ve been in several shops were an in-depth conversation surrounding OAuth2 client credentials authentication or generic/service accounts should be used by systems and applications. The granularity of the authorization requirements (how complicated is the authorization decision) and capabilities of the IdP will guide the answer to this question. In one case, the organization planned from the earliest stages to use Active Directory service accounts for application authentication; however, after the first ten applications were in production, every instance that involved application authentication (and no end user authentication) used the OAuth2 Client Credentials Grant.

This post concludes our demonstration of the four OAuth2 Authorization Grants with Red Hat SSO.