Skip to content

Instantly share code, notes, and snippets.

@rac021
Created March 9, 2017 18:30
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rac021/623e4f4c87069acd0c38d952568f8a3d to your computer and use it in GitHub Desktop.
Save rac021/623e4f4c87069acd0c38d952568f8a3d to your computer and use it in GitHub Desktop.
## Obtain Token and Invoke Service
@rac021
Copy link
Author

rac021 commented Mar 9, 2017

Obtain Token and Invoke Service

Keycloak allows you to make direct REST invocations to obtain an access token. To use it you must also have registered a valid Client to use as the "client_id" for this grant request.

1.So first we need to create a client that can be used to obtain the token. Go to the Keycloak admin console and create a new client. Give the Client ID a name and select public for access type.

Then in Settings, set "Direct Grants Only" on, and This switch is for clients that only use the Direct Access Grant protocol to obtain access tokens. Under Web Origins URIs enter you keycloak root (for example, https://auth.wpic-tools.com/auth)

As we are going to manually obtain a token and invoke the service let's increase the lifespan of tokens slightly. In production access tokens should have a relatively low timeout, ideally less than 5 minutes. To increase the timeout go to the Keycloak admin console again. This time click on Realm Settings then on Tokens. Change the value of Access Token Lifespan to 15 minutes. That should give us plenty of time to obtain a token and invoke the service before it expires.

In order to get a token, The REST URL to invoke on is /{keycloak-root}/realms/{realm-name}/protocol/openid-connect/token

Now we're ready to get our first token using CURL. To do this run:

RESULT=`curl --data "grant_type=password&client_id=curl&username=yourusername&password=*****" https://auth.wpic-tools.com/auth/realms/wpic/protocol/openid-connect/token`

Basically what we are doing here is invoking Keycloaks OpenID Connect token endpoint with grant type set to password which is the Resource Owner Credentials flow that allows swapping a username and a password for a token.
Take a look at the result by running:
echo $RESULT

For public client's, the POST invocation requires form parameters that contain the username, credentials, and client_id of your application. For example:

POST /auth/realms/demo/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

username=bburke&password=geheim&client_id=curl&grant_type=password

2.The result is a JSON document that contains a number of properties. There's only one we need for now though so we need to parse this output to retrieve only the value we want. To do this run:

TOKEN=`echo $RESULT | sed 's/.*access_token":"//g' | sed 's/".*//g'`

This command uses sed to strip out everything before and after the value of the access token property.

3.Now that we have the token we can invoke the secured service. To do this run:

curl https://squirrel-staging.wpic-tools.com/rest/tasks -H "Authorization: bearer $TOKEN"

@vbalas
Copy link

vbalas commented Oct 20, 2017

How does the resource server in this case squirrel-staging.wpic-tools.com/ verify the bearer token ?

@gigaga
Copy link

gigaga commented Nov 23, 2017

Hi,

Can you explain how obtain an access_token for a specific identity provider ?
By this way, password is checked from internal Keycloak database. For example how indicate what idp I want use to check user/pass couple?

Thx

@TJarriault
Copy link

hi,
i've got the same question.
Can you explain how obtain an access_token for a specific identity provider ?

Regards,

@vayalaivadivel
Copy link

I am not able to find any rest api to validate the token.
Please anyone can help me on this.

Thanks,
Vadivel PM.

@IvanAR
Copy link

IvanAR commented Dec 11, 2017

Same here, I'm having problems on how to validate the token on destiny service

@fquiroz
Copy link

fquiroz commented Mar 13, 2018

it works , but in Postman app with the same parametes not working

@j0zeft
Copy link

j0zeft commented Jun 25, 2018

If I understand correctly, I think if you have the certificate installed on the application server (only the certificate without the private key), this should be enough to verify the signature on the JWT coming from the Identity provider (Keycloak)...

@divanshArora
Copy link

Worked well. Thanks for this

@runeksvendsen
Copy link

The token is verified/validated using the public key of the Keycloak server.

In Keycloak:

  1. Go to Realm Settings -> Keys and click the Public key button for the key with the highest priority
  2. A popup appears with long string of text (the public key)
  3. Copy/paste this public key
  4. In the backend: use a JWT library and provide it the public key to verify that the token is valid

@jbouder
Copy link

jbouder commented Jan 22, 2022

Have you by chance tried using the rest api within a web application to get a token? Particularly from something like a React app? No matter what I try I can’t seem to get it to work.

@MarcusBondezan
Copy link

Have you by chance tried using the rest api within a web application to get a token? Particularly from something like a React app? No matter what I try I can’t seem to get it to work.

@jbouder I'm having the same problem. I have a react app and I'm trying to use my own UI login screen and trying to call the keycloak rest endpoint that gives me the access token.

Have you find out how to do it properly?

@jbouder
Copy link

jbouder commented Mar 28, 2022

I did actually, the main issue I was experiencing actually was due to how I was posting my data, was using FormData, when it should actually be UrlSearchParams. Here is the gist of what I'm doing (might have to tweak a bit, i'm using a default axios instance, and for this code snipped I pulled some of that in for you)...
axios({ method: 'post', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, url: '${SSO_ISSUER_URL}/realms/${SSO_KEYCLOAK_REALM}/protocol/openid-connect/token', data: new URLSearchParams({ client_id: SSO_CLIENT_ID, grant_type: 'password', username: USERNAME, password: PASSWORD, })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment