In this article we will share with you our understanding of oauth2 bearer token usage with RedHat SSO Keycloak.

1. Overview 

Access Token are defined by RFC 6750, and are of type Bearer Token.

Access Tokens are used to access to the content of a resource according to Oauth2 specification (RFC 6749).
The way to request access to resource is to use a bearer token type query in the request to the resource server, which will grant or deny access.
An access token is  of type of bearer token and is passed as parameter in the Oauth2 authorisation header query.

An access token is like a ticket which has got a time lifespan. It is delivered to the user, and allows access to the resource after validation
by the authorization sever.

2. Access token query example
Here an access token query example  returned from the RH-SSO token endpoint.

curl \
-d "client_id=admin-cli" \
-d "username=admin" \
-d "password=admin" \
-d "grant_type=password" \
"https://localhost:8180/auth/realms/master/protocol/openid-connect/token" | jq
% Total
% Received % Xferd Average Speed Time Time
Dload Upload Total Spent
100 6292 100 6223 100
69 46145
Time Current
Left Speed
511 --:--:-- --:--:-- --:--:-- 46440
{
"access_token":
"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ1ZnJ2czB4YzFsc1RfdnVsbG1KNlp
XUDdSemVXOHA2Y0hyN2xWV2hRdlRNIn0.eyJqdGkiOiIzNmRhOGI3OC1iYmU5LTQ5ZDgt
..............................................................
...............................................................
vB1lf5LILe66Qg3C3QtPiauzVUtq9EscesFRcuNO3-EsEXfb-
k3xfnbAdId1S557fd2h5xtClNAsX3lhrdOLA",
"expires_in": 60,
"refresh_expires_in": 1800,

 

3. Access Token Instrospection

Below is shown how to access the access token content using the RH-SSO userinfo endpoint


1.
an access token is delivered to the user (access_token)
2. the user perform a query using the baccess token adding to the header: « Authorization: bearer $access_token »

step1 (1. an access token is delivered to the user (access_token))

access_token=$(curl \
-d "client_id=app-jsp" \
-d client_secret=5c5415e9-6272-4295-9fca-c1fea95d4617 \
-d "username=user" \
-d "password=password" \
-d "grant_type=password" \
"https://localhost:8180/auth/realms/rh-quickstart/protocol/openid-connect/token" | jq -r
'.access_token')



step2: (2. the user perform a query using the baccess token adding to the header: "Authorization: bearer $access_token")

An access token response is obtained as follows:

curl -H "Authorization: bearer $access_token" https://localhost:8180/auth/realms/rh-
quickstart/protocol/openid-connect/userinfo | jq

{
"sub": "22c43429-b4ba-44ff-b57e-d109779a1467",
"name": "",
"preferred_username": "user"
}

 

4. RH-SSO Bearer token type allocator

In RH-SSO, it is possible to define clients:

  • using clientID/Client secret
  • using signed JWT
  • using bearer token

When application provides « Bearer token » as RH-SSO client authentication method, it means that:

  • there is no login interface to connect to the application
  • The only way to connect to the application is to use a bearer token (I.e access token).

 

In RH-SSO there is an example at
~/keycloak-2.5.x/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java

A bearer token is added to the authorizaton header with the bearer syntax: addHeader(« Authorization », « Bearer  » + session.getTokenString().

KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
return session.getIdToken();

}

public static List getCustomers(HttpServletRequest req) throws Failure {
KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());

HttpClient client = new DefaultHttpClient();
try {
HttpGet get = new HttpGet(UriUtils.getOrigin(req.getRequestURL().toString()) + "/database/customers");
get.addHeader("Authorization", "Bearer " + session.getTokenString());
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() != 200) {
throw new Failure(response.getStatusLine().getStatusCode());
}

 

 

janua
Les derniers articles par janua (tout voir)