0

I try to implement a simple OAuth2 "Client Authentication with Signed JWT" Demo App using Spring Boot and Keycloak as AuthService.

The idea is:

  1. one secured REST service "The Producer"
    • offering an endpoint GET /person for all users/principals with the role "read_person"
    • offering an endpoint POST /person for all users/principals with the role "write_person"
  2. another (unsecured) REST service "The Consumer"
    • offering an enpoint /api open for everybody
    • calling internal the "producer" viaFeignclient using an RequestInterceptor to pass the AccessToken (signed JWT / JWS)

I read about the docs:

http://www.keycloak.org/docs/latest/securing_apps/topics/oidc/java/client-authentication.html

saying:

Once the client application is started, it allows to download its public >key in JWKS format using a URL such as http://myhost.com/myapp/k_jwks, >assuming that http://myhost.com/myapp is the base URL of your client >application. This URL can be used by Keycloak (see below).

During authentication, the client generates a JWT token and signs it with >its private key and sends it to Keycloak in the particular backchannel >request (for example, code-to-token request) in the client_assertion >parameter.

I googled a lot to find tutorials/demos or docs about this topic but failed so far. So here my questions:

  1. How do I implement this "k_jwk" endpoint? Do I simple build a @RestController by myself in "the Producer"? How do I configure Keycloak to get aware of this URL?

  2. How do I implement my "Consumer" to get fresh signed JWT from Keycloak?

Update Removed irritating PS statement.

HaVonTe
  • 145
  • 1
  • 3
  • 15
  • Why are you reimplementing all of this since we already do that in the Spring Boot Adapter ? – Sébastien Blanc Oct 16 '17 at 09:09
  • Please show me how to use the Keycloak Adapater here. I cant find any demos or docs. – HaVonTe Oct 16 '17 at 12:04
  • http://www.keycloak.org/docs/latest/securing_apps/topics/oidc/java/spring-boot-adapter.html , check my blogpost as well https://developers.redhat.com/blog/2017/05/25/easily-secure-your-spring-boot-applications-with-keycloak/ or our quickstarts https://github.com/keycloak/keycloak-quickstarts – Sébastien Blanc Oct 16 '17 at 12:21
  • I cannot find any documentation about using signed JWT on your blog or in these quickstarts. – HaVonTe Oct 16 '17 at 13:45
  • Well it's not documentated because it's done internally and if you use the adapter you don't have to care about this , if you want to reimplement what our adapters does check the source code of the Keycloak project. – Sébastien Blanc Oct 16 '17 at 13:54
  • I dont want to reimplement anything. I want to use it. But it is Not documented how to do it. I can use id + secret and everything but when I set the realm client to "signed jwt" i am alone in the dark. Pls tell me how to use the Adapter with signed jwt. – HaVonTe Oct 16 '17 at 15:22
  • Sorry I completly missed the *client* part of your question about signed JWT. Let me give an answer below. – Sébastien Blanc Oct 17 '17 at 07:05

2 Answers2

2
  1. You don't need to implement the k_jwk endpoint, this is handled by the adapter. Keycloak will by default look at http:///your.app.com/k_jwk(but if needed you can override that in the console). Then you need to configure your Spring Boot client, just use the same properties as the keycloak.json but in the application.properties format:

    ...

    keycloak.credentials.jwt.client-keystore-file=classpath:keystore-client.jks keycloak.credentials.jwt.client-keystore-type=JKS

    etc ...

  2. You need a token to call the producerbut as you said the entry point will be an insecured endpoint so you might want to use a Service Account for this.

I hope this will help.

Aritz
  • 30,971
  • 16
  • 136
  • 217
Sébastien Blanc
  • 2,929
  • 1
  • 12
  • 11
  • Ok, thx. The first Info is very handy. I will try to understand and implement this Service Account topic. – HaVonTe Oct 17 '17 at 22:28
  • I could need further assistance here. I setup a client app with the proper keycloak settings and the adapter in the gradle dependencies. I created a Feign Client (RestTemplate would be fine too for me). Now what? How do I generate a JWT? I dont understand the hint with the Service Account. The doc says: http://www.keycloak.org/docs/2.5/server_admin/topics/clients/oidc/service-accounts.html Summarized: grab the token from keycloak by POST /auth/realms/demo/protocol/openid-connect/token so I have to write this by myselft? – HaVonTe Nov 15 '17 at 15:41
  • 1
    Yes, if you want to use a signed JWT as client authentification, there is probably some manual work to do but you could leverage this class to get the jwt token https://github.com/keycloak/keycloak/blob/master/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authentication/JWTClientCredentialsProvider.java – Sébastien Blanc Nov 23 '17 at 09:08
0

Update

I couldnt solve this issue but learned some things about singned JWT in the mean time:

  1. create a so called "Bearer Token" by creating a Json Structure with all necessary claims (sub, nbf, exp ...) by yourself and sign/certificate it with your JKS/Private Key from Keycloak. There are some nice third party libs beside Keycloak to do this.

  2. To get a real AccessToken (JWE/JWS) from Keycloak: send this static final Bearer Token to Keycloak at /auth/realms/$realm/protocol/openid-connect/token/introspect

with QueryParams:

grant_type=client_credentials&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=$BEARER_TOKEN

  1. Use the received real AccessToken to access the ResourceServer...
HaVonTe
  • 145
  • 1
  • 3
  • 15
  • I have a similar problem, so could you show a piece of code to get a token from keycloak using jwt and spring boot? please.. PS if you want this is my question: [https://stackoverflow.com/questions/49900124/can-i-pass-a-principal-with-rest-template-if-im-using-an-async-task-wiht-spring](https://stackoverflow.com/questions/49900124/can-i-pass-a-principal-with-rest-template-if-im-using-an-async-task-wiht-spring) – Teo Apr 28 '18 at 07:03