-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'knative-extensions:main' into feature/support-expose-au…
…dience-of-broker
- Loading branch information
Showing
72 changed files
with
13,387 additions
and
8,530 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
...e/core/src/main/java/dev/knative/eventing/kafka/broker/core/oidc/OIDCDiscoveryConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
* Copyright © 2018 Knative Authors (knative-dev@googlegroups.com) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package dev.knative.eventing.kafka.broker.core.oidc; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import io.fabric8.kubernetes.client.Config; | ||
import io.fabric8.kubernetes.client.ConfigBuilder; | ||
import io.vertx.core.Future; | ||
import io.vertx.core.Vertx; | ||
import io.vertx.core.net.PemTrustOptions; | ||
import io.vertx.ext.web.client.WebClient; | ||
import io.vertx.ext.web.client.WebClientOptions; | ||
import org.jose4j.jwk.JsonWebKeySet; | ||
import org.jose4j.keys.resolvers.JwksVerificationKeyResolver; | ||
import org.jose4j.lang.JoseException; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class OIDCDiscoveryConfig { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(TokenVerifier.class); | ||
|
||
private String issuer; | ||
|
||
private JwksVerificationKeyResolver jwksVerificationKeyResolver; | ||
|
||
private OIDCDiscoveryConfig() {} | ||
|
||
public String getIssuer() { | ||
return issuer; | ||
} | ||
|
||
public JwksVerificationKeyResolver getJwksVerificationKeyResolver() { | ||
return jwksVerificationKeyResolver; | ||
} | ||
|
||
public static Future<OIDCDiscoveryConfig> build(Vertx vertx) { | ||
Config kubeConfig = new ConfigBuilder().build(); | ||
|
||
WebClientOptions webClientOptions = new WebClientOptions() | ||
.setPemTrustOptions(new PemTrustOptions().addCertPath(kubeConfig.getCaCertFile())); | ||
WebClient webClient = WebClient.create(vertx, webClientOptions); | ||
|
||
OIDCDiscoveryConfig oidcDiscoveryConfig = new OIDCDiscoveryConfig(); | ||
|
||
return webClient | ||
.getAbs("https://kubernetes.default.svc/.well-known/openid-configuration") | ||
.bearerTokenAuthentication(kubeConfig.getAutoOAuthToken()) | ||
.send() | ||
.compose(res -> { | ||
logger.debug("Got raw OIDC discovery info: " + res.bodyAsString()); | ||
|
||
try { | ||
ObjectMapper mapper = new ObjectMapper(); | ||
OIDCInfo oidcInfo = mapper.readValue(res.bodyAsString(), OIDCInfo.class); | ||
|
||
oidcDiscoveryConfig.issuer = oidcInfo.getIssuer(); | ||
|
||
return webClient | ||
.getAbs(oidcInfo.getJwks().toString()) | ||
.bearerTokenAuthentication(kubeConfig.getAutoOAuthToken()) | ||
.send(); | ||
|
||
} catch (JsonProcessingException e) { | ||
logger.error("Failed to parse OIDC discovery info", e); | ||
|
||
return Future.failedFuture(e); | ||
} | ||
}) | ||
.compose(res -> { | ||
if (res.statusCode() >= 200 && res.statusCode() < 300) { | ||
try { | ||
JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(res.bodyAsString()); | ||
logger.debug("Got JWKeys: " + jsonWebKeySet.toJson()); | ||
|
||
oidcDiscoveryConfig.jwksVerificationKeyResolver = | ||
new JwksVerificationKeyResolver(jsonWebKeySet.getJsonWebKeys()); | ||
|
||
return Future.succeededFuture(oidcDiscoveryConfig); | ||
} catch (JoseException t) { | ||
logger.error("Failed to parse JWKeys", t); | ||
|
||
return Future.failedFuture(t); | ||
} | ||
} | ||
|
||
logger.error("Got unexpected response code for JWKey URL: " + res.statusCode()); | ||
|
||
return Future.failedFuture("unexpected response code on JWKeys URL: " + res.statusCode()); | ||
}); | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
data-plane/core/src/main/java/dev/knative/eventing/kafka/broker/core/oidc/OIDCInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright © 2018 Knative Authors (knative-dev@googlegroups.com) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package dev.knative.eventing.kafka.broker.core.oidc; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import java.net.URL; | ||
|
||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
class OIDCInfo { | ||
|
||
private String issuer; | ||
|
||
@JsonProperty("jwks_uri") | ||
private URL jwks; | ||
|
||
public String getIssuer() { | ||
return issuer; | ||
} | ||
|
||
public void setIssuer(String issuer) { | ||
this.issuer = issuer; | ||
} | ||
|
||
public URL getJwks() { | ||
return jwks; | ||
} | ||
|
||
public void setJwks(URL jwks) { | ||
this.jwks = jwks; | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
data-plane/core/src/main/java/dev/knative/eventing/kafka/broker/core/oidc/TokenVerifier.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright © 2018 Knative Authors (knative-dev@googlegroups.com) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package dev.knative.eventing.kafka.broker.core.oidc; | ||
|
||
import io.vertx.core.Future; | ||
import io.vertx.core.Vertx; | ||
import io.vertx.core.http.HttpServerRequest; | ||
import org.jose4j.jwt.JwtClaims; | ||
import org.jose4j.jwt.consumer.InvalidJwtException; | ||
import org.jose4j.jwt.consumer.JwtConsumer; | ||
import org.jose4j.jwt.consumer.JwtConsumerBuilder; | ||
import org.jose4j.jwt.consumer.JwtContext; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class TokenVerifier { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(TokenVerifier.class); | ||
|
||
private final Vertx vertx; | ||
|
||
private final OIDCDiscoveryConfig oidcDiscoveryConfig; | ||
|
||
public TokenVerifier(Vertx vertx, OIDCDiscoveryConfig oidcDiscoveryConfig) { | ||
this.vertx = vertx; | ||
this.oidcDiscoveryConfig = oidcDiscoveryConfig; | ||
} | ||
|
||
public Future<JwtClaims> verify(String token, String expectedAudience) { | ||
return this.vertx.<JwtClaims>executeBlocking(promise -> { | ||
// execute blocking, as jose .process() is blocking | ||
|
||
JwtConsumer jwtConsumer = new JwtConsumerBuilder() | ||
.setVerificationKeyResolver(this.oidcDiscoveryConfig.getJwksVerificationKeyResolver()) | ||
.setExpectedAudience(expectedAudience) | ||
.setExpectedIssuer(this.oidcDiscoveryConfig.getIssuer()) | ||
.build(); | ||
|
||
try { | ||
JwtContext jwtContext = jwtConsumer.process(token); | ||
|
||
promise.complete(jwtContext.getJwtClaims()); | ||
} catch (InvalidJwtException e) { | ||
promise.fail(e); | ||
} | ||
}); | ||
} | ||
|
||
public Future<JwtClaims> verify(HttpServerRequest request, String expectedAudience) { | ||
String authHeader = request.getHeader("Authorization"); | ||
if (authHeader.isEmpty()) { | ||
return Future.failedFuture("Request didn't contain Authorization header"); // change to exception | ||
} | ||
|
||
if (!authHeader.startsWith("Bearer ") && authHeader.length() <= "Bearer ".length()) { | ||
return Future.failedFuture("Authorization header didn't contain Bearer token"); // change to exception | ||
} | ||
|
||
String token = authHeader.substring("Bearer ".length()); | ||
logger.debug("Extracted token \"{}\" from request auth header \"{}\"", token, authHeader); | ||
|
||
return verify(token, expectedAudience); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.