简体   繁体   中英

Implementing JWT, JWE and JWS (signed JWT) with Keycloak in Spring Boot

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" via Feign client 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.

  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 producer but 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.

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM