ivangfr / springboot-react-keycloak

The goal of this project is to secure movies-app using Keycloak (with PKCE). movies-app consists of two applications: one is a Spring Boot Rest API called movies-api and another is a React application called movies-ui.
398 stars 156 forks source link

Revoking Token in Keycloak #15

Closed AdigaAkhil closed 1 year ago

AdigaAkhil commented 1 year ago

Hello @ivangfr ,

Firstly, great project! loved it. It covers everything from the backend and front end. However, I had some queries regarding Keycloak in your project.

As far as I have done research the only API to revoke a token is the /revoke API which looks like this

http://localhost:8080/realms/<realm-name>/protocol/openid-connect/revoke Along with this URL we will also be using clientId,client-secret, token_type and the actual token we want to revoke.

My query is, if we use the PKCE apporoach there is no client-secret ,so how do we revoke the token since the client secret is not optional

The same query applies for the introspect endpoint as well

http://localhost:8080/realms/<realm-name>/protocol/openid-connect/token/introspect

ivangfr commented 1 year ago

Hi @AdigaAkhil

I believe I got it partially. The introspect endpoint is returning 403 and the revoke is working.

I've used the app of this repo.

Get JWT token

$ curl -i -X POST \
  "http://localhost:8080/realms/company-services/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin" \
  -d "grant_type=password" \
  -d "client_id=movies-app"

Response

HTTP/1.1 200 OK
...
{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ5eEFURmwwbzNzVjg1QzNWU21DYXo1NTNRYXhyUTZsT2k1QngtdEpmcEFZIn0.eyJleHAiOjE2OTEzNTgwMzAsImlhdCI6MTY5MTM1NzczMCwianRpIjoiYzVmNmIwMWItNWRhNC00ZDVhLWEyODAtZTBjNDczMTYyNDE4IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9jb21wYW55LXNlcnZpY2VzIiwic3ViIjoiZWFkMDE1YTgtOThhNi00NDBiLWI1NDAtMjhiOWI0OTM0NWMzIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibW92aWVzLWFwcCIsInNlc3Npb25fc3RhdGUiOiJhNWJhNTU5Ny01OGJiLTQ3YWUtYjVlZC0zZTUxYjA4OWVmMTkiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCJdLCJyZXNvdXJjZV9hY2Nlc3MiOnsibW92aWVzLWFwcCI6eyJyb2xlcyI6WyJNT1ZJRVNfTUFOQUdFUiIsIk1PVklFU19VU0VSIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwic2lkIjoiYTViYTU1OTctNThiYi00N2FlLWI1ZWQtM2U1MWIwODllZjE5IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.gdEmu4zoimr2beNjniTSk4ZC4adhwhyxqUwTMUHFQ9CHnoiaB6a83TS5MDLoIr-_k4LJRMag11peGPMEy2cUT6ZAk_u9rXXep-no4skEd-GdHCeXb-ZSJiPykc8QY3ZS6gu3TiqKjMjoDldKAzH92RMmn9Aqd66r5yYJouG4KgmGqGFx72p3TpskQJ-A90Iikuw6fQ125g_XDDNFov-Zhms-1BBnKJX7J9vkmNnlEK9QQOR8YIGsoMbOiMWI57Vdmsqm0Maq1UJ92MJk6ZHcIrUIEiu-SLr2QO9DycjarocSNrHfP5kAFSpuJwvVHEC_sNPbO-bfAaIqOveE09Ht0Q",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzMzg4MzNjNS0wMzIwLTQzNWEtOGM4Yi1jYmZlZjEyODIxOWEifQ.eyJleHAiOjE2OTEzNTk1MzAsImlhdCI6MTY5MTM1NzczMCwianRpIjoiZjZjZmI1ODctY2RkMy00M2E3LWI3NzMtMjIzZTM5NzllMWQwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9jb21wYW55LXNlcnZpY2VzIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9jb21wYW55LXNlcnZpY2VzIiwic3ViIjoiZWFkMDE1YTgtOThhNi00NDBiLWI1NDAtMjhiOWI0OTM0NWMzIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6Im1vdmllcy1hcHAiLCJzZXNzaW9uX3N0YXRlIjoiYTViYTU1OTctNThiYi00N2FlLWI1ZWQtM2U1MWIwODllZjE5Iiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwic2lkIjoiYTViYTU1OTctNThiYi00N2FlLWI1ZWQtM2U1MWIwODllZjE5In0.GQ-mWo1mfQfuOEI20RHKzQut_DkM8rUu1Lfp9JmvkzM",
    "token_type": "Bearer",
    "not-before-policy": 0,
    "session_state": "a5ba5597-58bb-47ae-b5ed-3e51b089ef19",
    "scope": "email profile"
}

Set refresh_token to TOKEN env var

$ TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIzMzg4MzNjNS0wMzIwLTQzNWEtOGM4Yi1jYmZlZjEyODIxOWEifQ.eyJleHAiOjE2OTEzNTk1MzAsImlhdCI6MTY5MTM1NzczMCwianRpIjoiZjZjZmI1ODctY2RkMy00M2E3LWI3NzMtMjIzZTM5NzllMWQwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9jb21wYW55LXNlcnZpY2VzIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9jb21wYW55LXNlcnZpY2VzIiwic3ViIjoiZWFkMDE1YTgtOThhNi00NDBiLWI1NDAtMjhiOWI0OTM0NWMzIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6Im1vdmllcy1hcHAiLCJzZXNzaW9uX3N0YXRlIjoiYTViYTU1OTctNThiYi00N2FlLWI1ZWQtM2U1MWIwODllZjE5Iiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwic2lkIjoiYTViYTU1OTctNThiYi00N2FlLWI1ZWQtM2U1MWIwODllZjE5In0.GQ-mWo1mfQfuOEI20RHKzQut_DkM8rUu1Lfp9JmvkzM

Call introspect endpoint using TOKEN

$ curl -i -X POST http://localhost:8080/realms/company-services/protocol/openid-connect/token/introspect \
  -d token=$TOKEN \
  -d client_id=movies-app

Response

HTTP/1.1 403 Forbidden
...
{"error":"invalid_request","error_description":"Client not allowed."}

Probably, there is some config we need to set for the client.

Call revoke endpoint using TOKEN

$ curl -i -X POST http://localhost:8080/realms/company-services/protocol/openid-connect/revoke \
  -d token=$TOKEN \
  -d client_id=movies-app

Response

HTTP/1.1 200 OK
...
ivangfr commented 1 year ago

Hi @AdigaAkhil any feedback from your side on this issue? Thanks!

ivangfr commented 1 year ago

Closing issue as no feedback was provided.

AdigaAkhil commented 1 year ago

Sorry @ivangfr, I was out on vacation. Thank you for the response. I'll look into it and let you know.