Skip to content

Commit

Permalink
Adding possibility to supply the jwt private key as a string.
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanPuntev authored and sberyozkin committed Apr 16, 2024
1 parent 6139e8a commit b9be05f
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ quarkus.oidc.credentials.jwt.secret-provider.key=mysecret-key
quarkus.oidc.credentials.jwt.secret-provider.name=oidc-credentials-provider
----

Example of `private_key_jwt` with the PEM key inlined in application.properties, and where the signature algorithm is `RS256`:

[source,properties]
----
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/
quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.jwt.key=Base64-encoded private key representation
----

Example of `private_key_jwt` with the PEM key file, and where the signature algorithm is RS256:

[source,properties]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,15 @@ quarkus.oidc-client.credentials.jwt.secret-provider.key=mysecret-key
quarkus.oidc-client.credentials.jwt.secret-provider.name=oidc-credentials-provider
----

`private_key_jwt` with the PEM key inlined in application.properties, and where the signature algorithm is `RS256`:

[source,properties]
----
quarkus.oidc-client.auth-server-url=http://localhost:8180/auth/realms/quarkus/
quarkus.oidc-client.client-id=quarkus-app
quarkus.oidc-client.credentials.jwt.key=Base64-encoded private key representation
----

`private_key_jwt` with the PEM key file, signature algorithm is `RS256`:

[source,properties]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,14 @@ public void testClientCredentialsToken() {
.statusCode(200)
.body(equalTo("service-account-quarkus-app"));
}

@Test
public void testPrivateKeyToken() {
String token = RestAssured.when().get("/client/token-key").body().asString();
RestAssured.given().auth().oauth2(token)
.when().get("/protected")
.then()
.statusCode(200)
.body(equalTo("service-account-quarkus-app"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ public class OidcClientResource {
@Inject
OidcClient client;

@Inject
@NamedOidcClient("key")
OidcClient keyClient;

@GET
@Path("token-key")
public Uni<String> tokenFromPrivateKeyUni() {
return keyClient.getTokens().flatMap(tokens -> Uni.createFrom().item(tokens.getAccessToken()));
}

@GET
@Path("token")
public Uni<String> tokenUni() {
Expand All @@ -23,13 +33,13 @@ public Uni<String> tokenUni() {
@GET
@Path("tokens")
public Uni<String> grantTokensUni() {
return client.getTokens().flatMap(tokens -> createTokensString(tokens));
return client.getTokens().flatMap(this::createTokensString);
}

@GET
@Path("refresh-tokens")
public Uni<String> refreshGrantTokens(@QueryParam("refreshToken") String refreshToken) {
return client.refreshTokens(refreshToken).flatMap(tokens -> createTokensString(tokens));
return client.refreshTokens(refreshToken).flatMap(this::createTokensString);
}

private Uni<String> createTokensString(Tokens tokens) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public Uni<String> tokenUni(@PathParam("id") String oidcClientId) {
@GET
@Path("tokens/{id}")
public Uni<String> grantTokensUni(@PathParam("id") String oidcClientId) {
return getClient(oidcClientId).getTokens().flatMap(tokens -> createTokensString(tokens));
return getClient(oidcClientId).getTokens().flatMap(this::createTokensString);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ quarkus.oidc.client-id=quarkus-app
quarkus.oidc-client.auth-server-url=${quarkus.oidc.auth-server-url}
quarkus.oidc-client.client-id=${quarkus.oidc.client-id}
quarkus.oidc-client.credentials.jwt.key-file=/privateKey.pem

quarkus.oidc-client.key.auth-server-url=${quarkus.oidc.auth-server-url}
quarkus.oidc-client.key.client-id=${quarkus.oidc.client-id}
quarkus.oidc-client.key.credentials.jwt.key=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyXwKqKL/hQWDkurdHyRn/9aZqmrgpCfiT5+gQ7KZ9RvDjgTqkJT6IIrRFvIpeBMwSsw3dkUPGmgN1J4QOhLaR2VEXhc20UbxFbr6HXAskZGPuCL1tzRWDkLNMZaEO8jqhPbcq1Ro4GMhaSdm0sBHmcQnu8wAOrdAowdzGh/HUaaYBDY0OZVAm9N8zzBXTahna9frJCMHq3e9szIiv6HYZTy1672/+hR/0D1HY+bqpQtJnzSrKjkFeXDAbYPgewYLEJ2Dk+oo6L1I6S+UTrl4FRHw1fHAd2i75JD+vL/8w/AtKkej0CCBUSZJiV+KDJWjnDUVRWjq5hQb9pu4qEJKhAgMBAAECggEAJvBs4X7B3MfsAiLszgQN4/3ZlZ4vI+5kUM2osMEo22J4RgI5Lgpfa1LALhUp07qSXmauWTdUJ3AJ3zKANrcsMAzUEiGItZu+UR4LA/vJBunPkvBfgi/qSW12ZvAsx9mDiR2y9evNrH9khalnmHVzgu4ccAimc43oSm1/5+tXlLoZ1QK/FohxBxAshtuDHGs8yKUL0jpv7dOrjhCj2ibmPYe6AUk9F61sVWO0/i0Q8UAOcYT3L5nCS5WnLhdCdYpIJJ7xl2PrVE/BAD+JEG5uCOYfVeYh+iCZVfpX17ryfNNUaBtyxKEGVtHbje3mO86mYN3noaS0w/zpUjBPgV+KEQKBgQDsp6VTmDIqHFTp2cC2yrDMxRznif92EGv7ccJDZtbTC37mAuf2J7x5b6AiE1EfxEXyGYzSk99sCns+GbL1EHABUt5pimDCl33b6XvuccQNpnJ0MfM5eRX9Ogyt/OKdDRnQsvrTPNCWOyJjvG01HQM4mfxaBBnxnvl5meH2pyG/ZQKBgQDA87DnyqEFhTDLX5c1TtwHSRj2xeTPGKG0GyxOJXcxR8nhtY9ee0kyLZ14RytnOxKarCFgYXeG4IoGEc/I42WbA4sq88tZcbe4IJkdX0WLMqOTdMrdx9hMU1ytKVUglUJZBVm7FaTQjA+ArMwqkXAA5HBMtArUsfJKUt3l0hMIjQKBgQDS1vmAZJQs2Fj+jzYWpLaneOWrk1K5yR+rQUql6jVyiUdhfS1ULUrJlh3Avh0EhEUc0I6Z/YyMITpztUmu9BoV09K7jMFwHK/RAU+cvFbDIovN4cKkbbCdjt5FFIyBB278dLjrAb+EWOLmoLVbIKICB47AU+8ZSV1SbTrYGUcD0QKBgQCAliZv4na6sg9ZiUPAr+QsKserNSiN5zFkULOPBKLRQbFFbPS1l12pRgLqNCu1qQV19H5tt6arSRpSfy5FB14gFxV4s23yFrnDyF2h2GsFH+MpEq1bbaI1A10AvUnQ5AeKQemRpxPmM2DldMK/H5tPzO0WAOoy4r/ATkc4sG4kxQKBgBL9neT0TmJtxlYGzjNcjdJXs3Q91+nZt3DRMGT9s0917SuP77+FdJYocDiH1rVa9sGG8rkh1jTdqliAxDXwIm5IGS/0OBnkaN1nnGDk5yTiYxOutC5NSj7ecI5Erud8swW6iGqgz2ioFpGxxIYqRlgTv/6mVt41KALfKrYIkVLw
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface OidcRequestFilter {
* Filter OIDC requests
*
* @param request HTTP request that can have its headers customized
* @param body request body, will be null for HTTP GET methods, may be null for other HTTP methods
* @param requestBody request body, will be null for HTTP GET methods, may be null for other HTTP methods
* @param contextProperties context properties that can be available in context of some requests
*/
void filter(HttpRequest<Buffer> request, Buffer requestBody, OidcRequestContextProperties contextProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ public static enum Source {
@ConfigItem
public Provider secretProvider = new Provider();

/**
* String representation of a private key. If provided, indicates that JWT is signed using a private key in PEM or
* JWK format.
* You can use the {@link #signatureAlgorithm} property to override the default key algorithm, `RS256`.
*/
@ConfigItem
public Optional<String> key = Optional.empty();

/**
* If provided, indicates that JWT is signed using a private key in PEM or JWK format.
* You can use the {@link #signatureAlgorithm} property to override the default key algorithm, `RS256`.
Expand Down Expand Up @@ -399,6 +407,14 @@ public void setAudience(String audience) {
this.audience = Optional.of(audience);
}

public Optional<String> getKey() {
return key;
}

public void setKey(String key) {
this.key = Optional.of(key);
}

public Optional<String> getKeyFile() {
return keyFile;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ public static boolean isClientSecretBasicAuthRequired(Credentials creds) {
}

public static boolean isClientJwtAuthRequired(Credentials creds) {
return creds.jwt.secret.isPresent() || creds.jwt.secretProvider.key.isPresent() || creds.jwt.keyFile.isPresent()
|| creds.jwt.keyStoreFile.isPresent();
return creds.jwt.secret.isPresent() || creds.jwt.secretProvider.key.isPresent() || creds.jwt.key.isPresent()
|| creds.jwt.keyFile.isPresent() || creds.jwt.keyStoreFile.isPresent();
}

public static boolean isClientSecretPostAuthRequired(Credentials creds) {
Expand Down Expand Up @@ -329,7 +329,10 @@ public static Key clientJwtKey(Credentials creds) {
} else {
Key key = null;
try {
if (creds.jwt.getKeyFile().isPresent()) {
if (creds.jwt.getKey().isPresent()) {
key = KeyUtils.tryAsPemSigningPrivateKey(creds.jwt.getKey().get(),
getSignatureAlgorithm(creds, SignatureAlgorithm.RS256));
} else if (creds.jwt.getKeyFile().isPresent()) {
key = KeyUtils.readSigningKey(creds.jwt.getKeyFile().get(), creds.jwt.keyId.orElse(null),
getSignatureAlgorithm(creds, SignatureAlgorithm.RS256));
} else if (creds.jwt.keyStoreFile.isPresent()) {
Expand Down

0 comments on commit b9be05f

Please sign in to comment.