Skip to content

Commit 95fe331

Browse files
OauthBearer validation filter (kroxylicious#1195)
* oauthbearer filter * fail if not handshake before authenticate * fail early if saslServer is unset * fail fast if handshake with a sasl server exists --------- Co-authored-by: kwall <kwall@apache.org>
1 parent b67b945 commit 95fe331

File tree

16 files changed

+1221
-9
lines changed

16 files changed

+1221
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Format `<github issue/pr number>: <short description>`.
77

88
## SNAPSHOT
99

10+
* [#1195](https://github.com/kroxylicious/kroxylicious/pull/1195): SASL OAUTHBEARER validation filter
1011
* [#1076](https://github.com/kroxylicious/kroxylicious/issues/1076): AWS KMS implementation for Record Encryption
1112
* [#1201](https://github.com/kroxylicious/kroxylicious/pull/1201): Bump com.fasterxml.jackson:jackson-bom from 2.17.0 to 2.17.1
1213
* [#1158](https://github.com/kroxylicious/kroxylicious/pull/1158): Bump io.netty:netty-bom from 4.1.108.Final to 4.1.109.Final
@@ -210,5 +211,4 @@ The names used to identify micrometer configuration hooks in configuration have
210211
- `StandardBindersContributor` -> `StandardBindersHook`
211212
-
212213
#### CVE Fixes
213-
CVE-2023-44487 [#675](https://github.com/kroxylicious/kroxylicious/pull/675)
214-
214+
CVE-2023-44487 [#675](https://github.com/kroxylicious/kroxylicious/pull/675)

docs/available-filters.adoc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ The following filters are provided built-in as part of the distribution.
77
include::available-filters/record-encryption/record-encryption.adoc[leveloffset=2]
88
include::available-filters/multi-tenancy/multi-tenancy.adoc[leveloffset=2]
99
include::available-filters//schema-validation/schema-validation.adoc[leveloffset=2]
10+
include::available-filters/oauthbearer/oauthbearer.adoc[leveloffset=2]
1011

1112
== Community filters
1213

1314
Community contributed filters are showcased in the
14-
https://github.com/kroxylicious/kroxylicious-community-gallery[Community Gallery].
15-
16-
15+
https://github.com/kroxylicious/kroxylicious-community-gallery[Community Gallery].
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
= OAUTHBEARER validation
2+
3+
== What is it?
4+
5+
OauthBearerValidation filter enables a validation on the JWT token received from client before forwarding it to cluster.
6+
7+
If the token is not validated, then the request is short-circuited.
8+
It reduces resource consumption on the cluster when a client sends too many invalid SASL requests.
9+
10+
[mermaid]
11+
....
12+
sequenceDiagram
13+
Client->>Kroxylicious: Handshake request
14+
Kroxylicious->>Cluster: Forward Handshake request
15+
Cluster-->>Kroxylicious: Handshake response
16+
Kroxylicious-->>Client: Handshake response
17+
Client->>Kroxylicious: Authenticate request
18+
Kroxylicious->>Kroxylicious: Validate token
19+
break Token validation fails
20+
Kroxylicious->>Client: Invalid token
21+
end
22+
Kroxylicious->>Cluster: Authenticate request
23+
Cluster-->>Kroxylicious: Authenticate response
24+
Kroxylicious-->>Client: Authenticate response
25+
....
26+
27+
== How to use the filter
28+
29+
There are two steps to using the filter.
30+
31+
1. <<Configuring virtual clusters>>
32+
2. Configuring the filter within Kroxylicious.
33+
34+
=== Configuring the filter within Kroxylicious.
35+
36+
[source, yaml]
37+
----
38+
filters:
39+
- type: OauthBearerValidation
40+
config:
41+
jwksEndpointUrl: https://oauth/JWKS #<1>
42+
jwksEndpointRefreshMs: 3600000 #<2>
43+
jwksEndpointRetryBackoffMs: 100 #<3>
44+
jwksEndpointRetryBackoffMaxMs: 10000 #<4>
45+
scopeClaimName: scope #<5>
46+
subClaimName: sub #<6>
47+
authenticateBackOffMaxMs: 60000 #<7>
48+
authenticateCacheMaxSize: 1000 #<8>
49+
expectedAudience: https://first.audience, https//second.audience #<9>
50+
expectedIssuer: https://your-domain.auth/ #<10>
51+
----
52+
53+
<1> The OAuth/OIDC provider URL from which the provider's JWKS (JSON Web Key Set) can be retrieved.
54+
<2> The (optional) value in milliseconds for the broker to wait between refreshing its JWKS (JSON Web Key Set) cache that contains the keys to verify the signature of the JWT.
55+
<3> The (optional) value in milliseconds for the initial wait between JWKS (JSON Web Key Set) retrieval attempts from the external authentication provider.
56+
<4> The (optional) value in milliseconds for the maximum wait between attempts to retrieve the JWKS (JSON Web Key Set) from the external authentication provider.
57+
<5> This (optional) setting can provide a different name to use for the scope included in the JWT payload's claims.
58+
<6> This (optional) setting can provide a different name to use for the subject included in the JWT payload's claims.
59+
<7> The (optional) maximum value in milliseconds to limit the client sending authenticate request. Setting 0 will never limit the client. Otherwise, an exponential delay is added to each authenticate request until the authenticateBackOffMaxMs has been reached.
60+
<8> The (optional) maximum number of failed tokens kept in cache.
61+
<9> The (optional) comma-delimited setting for the broker to use to verify that the JWT was issued for one of the expected audiences.
62+
<10> The (optional) setting for the broker to use to verify that the JWT was created by the expected issuer.
63+
64+
Note: OauthBearer config follows https://kafka.apache.org/documentation/#security_ssl[kafka's properties]

kroxylicious-app/pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,12 @@
245245
<artifactId>kroxylicious-kms-provider-aws-kms</artifactId>
246246
<scope>runtime</scope>
247247
</dependency>
248+
<dependency>
249+
<groupId>io.kroxylicious</groupId>
250+
<artifactId>kroxylicious-oauthbearer-validation</artifactId>
251+
<scope>runtime</scope>
252+
</dependency>
248253
</dependencies>
249254
</profile>
250255
</profiles>
251-
</project>
256+
</project>

kroxylicious-bom/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@
171171
<version>${project.version}</version>
172172
</dependency>
173173

174+
<dependency>
175+
<groupId>io.kroxylicious</groupId>
176+
<artifactId>kroxylicious-oauthbearer-validation</artifactId>
177+
<version>${project.version}</version>
178+
</dependency>
179+
174180
<!-- testing dependencies -->
175181
<!-- note scope is *not* set at this level -->
176182
<dependency>
@@ -312,4 +318,4 @@
312318
</build>
313319
</profile>
314320
</profiles>
315-
</project>
321+
</project>
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright Kroxylicious Authors.
5+
6+
Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
7+
8+
-->
9+
10+
<project xmlns="http://maven.apache.org/POM/4.0.0"
11+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
12+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
13+
<modelVersion>4.0.0</modelVersion>
14+
<parent>
15+
<groupId>io.kroxylicious</groupId>
16+
<artifactId>kroxylicious-filter-parent</artifactId>
17+
<version>0.6.0-SNAPSHOT</version>
18+
<relativePath>../pom.xml</relativePath>
19+
</parent>
20+
21+
<artifactId>kroxylicious-oauthbearer-validation</artifactId>
22+
<packaging>jar</packaging>
23+
24+
<name>Oauthbearer filter</name>
25+
<description>Pre-validate oauth token before sending it to upstream kafka</description>
26+
27+
<dependencies>
28+
<!-- project dependencies - runtime and compile -->
29+
<dependency>
30+
<groupId>io.kroxylicious</groupId>
31+
<artifactId>kroxylicious-api</artifactId>
32+
</dependency>
33+
34+
<!-- third party dependencies - runtime and compile -->
35+
<dependency>
36+
<groupId>com.fasterxml.jackson.core</groupId>
37+
<artifactId>jackson-annotations</artifactId>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.apache.kafka</groupId>
41+
<artifactId>kafka-clients</artifactId>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.bitbucket.b_c</groupId>
45+
<artifactId>jose4j</artifactId>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.slf4j</groupId>
49+
<artifactId>slf4j-api</artifactId>
50+
</dependency>
51+
52+
<!-- project dependencies - test -->
53+
<dependency>
54+
<groupId>org.assertj</groupId>
55+
<artifactId>assertj-core</artifactId>
56+
<scope>test</scope>
57+
</dependency>
58+
<dependency>
59+
<groupId>org.junit.jupiter</groupId>
60+
<artifactId>junit-jupiter-api</artifactId>
61+
<scope>test</scope>
62+
</dependency>
63+
<dependency>
64+
<groupId>org.mockito</groupId>
65+
<artifactId>mockito-core</artifactId>
66+
<scope>test</scope>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.mockito</groupId>
70+
<artifactId>mockito-junit-jupiter</artifactId>
71+
<scope>test</scope>
72+
</dependency>
73+
<dependency>
74+
<groupId>com.fasterxml.jackson.core</groupId>
75+
<artifactId>jackson-databind</artifactId>
76+
<scope>test</scope>
77+
</dependency>
78+
<dependency>
79+
<groupId>com.fasterxml.jackson.dataformat</groupId>
80+
<artifactId>jackson-dataformat-yaml</artifactId>
81+
<scope>test</scope>
82+
</dependency>
83+
<dependency>
84+
<groupId>com.fasterxml.jackson.core</groupId>
85+
<artifactId>jackson-core</artifactId>
86+
<scope>test</scope>
87+
</dependency>
88+
<dependency>
89+
<groupId>io.kroxylicious</groupId>
90+
<artifactId>kroxylicious-annotations</artifactId>
91+
</dependency>
92+
<dependency>
93+
<groupId>com.github.spotbugs</groupId>
94+
<artifactId>spotbugs-annotations</artifactId>
95+
</dependency>
96+
<dependency>
97+
<groupId>com.github.ben-manes.caffeine</groupId>
98+
<artifactId>caffeine</artifactId>
99+
</dependency>
100+
<dependency>
101+
<groupId>io.kroxylicious</groupId>
102+
<artifactId>kroxylicious-filter-test-support</artifactId>
103+
<scope>test</scope>
104+
</dependency>
105+
</dependencies>
106+
<build>
107+
<plugins>
108+
<plugin>
109+
<groupId>org.apache.maven.plugins</groupId>
110+
<artifactId>maven-dependency-plugin</artifactId>
111+
<executions>
112+
<execution>
113+
<id>analyze</id>
114+
<configuration>
115+
<ignoredUnusedDeclaredDependencies>
116+
<ignoredUnusedDeclaredDependency>org.bitbucket.b_c:jose4j</ignoredUnusedDeclaredDependency>
117+
<ignoredUnusedDeclaredDependency>io.kroxylicious:kroxylicious-annotations</ignoredUnusedDeclaredDependency>
118+
</ignoredUnusedDeclaredDependencies>
119+
</configuration>
120+
</execution>
121+
</executions>
122+
</plugin>
123+
</plugins>
124+
</build>
125+
126+
</project>

0 commit comments

Comments
 (0)