lilalfyalien
lilalfyalien

Reputation: 263

Keycloak: Validate access token and get keycloak ID

I need to be able to do the following (with plain cURL & JSON server-side- no frameworks or Java):

  1. Use a string representation of a Keycloak access token I have been given by a 3rd party to verify that the token is valid.

  2. If the token is valid, get the Keycloak ID for that user.

How do I do this using plain old HTTP posts? I've found lots of Java examples but I need to know the raw HTTP POSTs and responses underneath.

Is it something like this to validate the token?

/auth/realms/<realm>/protocols/openid-connect/validate?access_token=accesstokenhere

What does this return in terms of data (sorry I currently have no test server to interrogate)?

Thanks.

Upvotes: 6

Views: 24359

Answers (3)

Elco
Elco

Reputation: 198

HOW TO VALIDATE TOKEN FROM KEYCLOAK BY USING KEYCLOAK API DIRECTLY:

curl --location --request POST '${keycloakBaseUrl}/realms/${keycloakRealm}/protocol/openid-connect/token/introspect' \
--header 'Authorization: Basic insert_auth_code_here' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=insert_refresh_token_here' \
--data-urlencode 'token_type_hint=refresh_token'

The Authorization: Basic <insert_auth_code_here> header in the curl command is a Base64-encoded string that represents the KEYCLOAK_CLIENT_ID:KEYCLOAK_CLIENT_SECRET required for basic authentication.

Converted to js fetch api:

import { encode } from 'base-64';


    const details = {
    token: token,
    token_type_hint: 'refresh_token',
    grant_type: 'password',
};

const body = new URLSearchParams(details).toString();


    const response = await fetch(`${keycloakUrl}/introspect`, {
        method: 'POST',
        headers: {
            'Authorization':
                'Basic ' + encode(`${keycloakClientId}:${keycloakClientSecret}`),
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body,
    });

Upvotes: 0

mssuley
mssuley

Reputation: 58

The validate endpoint does not seem to work now. It used to return access token. I am using the keycloak 2.5.1 now. As mentioned in post by Matyas (and in the post referenced by him), had to use introspect token endpoint.

In my testing Bearer authentication did not work. Had to use Basic authentication header along with base64 encoded client credentials.

base64.encode("<client_id:client_secret>".getBytes("utf-8"))

The response from introspect endpoint is in JSON format as shared in post referenced by Maytas, has many fields based on type of token being introspected. In my case token_type_hint was set as access_token.

requestParams = "token_type_hint=access_token&token=" + accessToken

The response included required user details like username, roles and resource access. Also included OAuth mandated attributes like active, exp, iss etc. See rfc7662#page-6 for details.

Upvotes: 3

user5963797
user5963797

Reputation:

Maybe you need this: http://lists.jboss.org/pipermail/keycloak-user/2016-April/005869.html

The only one problem is that, introspect is not working with public clients.

The key url is: "http://$KC_SERVER/$KC_CONTEXT/realms/$REALM/protocol/openid-connect/token/introspect"

You need to authorize your client e.g. with basic auth, and need to give the requester token to introspect:

curl -u "client_id:client_secret" -d "token=access_token_to_introspect" "http://$KC_SERVER/$KC_CONTEXT/realms/$REALM/protocol/openid-connect/token/introspect"

Upvotes: 4

Related Questions