24
24
import edu .umd .cs .findbugs .annotations .Nullable ;
25
25
import java .lang .reflect .InvocationTargetException ;
26
26
import java .lang .reflect .Method ;
27
+ import java .net .URI ;
28
+ import java .net .URISyntaxException ;
27
29
import java .nio .file .Path ;
28
30
import java .util .HashMap ;
29
31
import java .util .Map ;
30
32
import org .apache .kafka .common .config .AbstractConfig ;
31
33
import org .apache .kafka .common .config .ConfigDef ;
34
+ import org .apache .kafka .common .config .types .Password ;
35
+
32
36
import org .slf4j .Logger ;
33
37
import org .slf4j .LoggerFactory ;
34
38
@@ -39,7 +43,13 @@ public class AuthenticatorConfig extends AbstractConfig {
39
43
public static final String PASSWORD_OPT = "auth.password" ;
40
44
public static final String KEYTAB_OPT = "auth.gssapi.keyTab" ;
41
45
public static final String PRINCIPAL_OPT = "auth.gssapi.principal" ;
42
- public static final String SERVICE_OPT = "auth.gssapi.service" ;
46
+ public static final String SERVICE_OPT = "auth.gssapi.cservice" ;
47
+ public static final String OIDC_ISSUER_OPT = "auth.oidc.issuer" ;
48
+ public static final String OIDC_CLIENT_ID_OPT = "auth.oidc.client_id" ;
49
+ public static final String OIDC_CLIENT_SECRET_OPT = "auth.oidc.client_secret" ;
50
+ public static final String OIDC_USE_TLS_OPT = "auth.oidc.use_tls" ;
51
+ public static final String OIDC_TRUSTSTORE_PATH_OPT = "auth.oidc.truststore_path" ;
52
+ public static final String OIDC_TRUSTSTORE_PASSWORD_OPT = "auth.oidc.truststore_password" ;
43
53
44
54
private static final Logger log = LoggerFactory .getLogger (AuthenticatorConfig .class );
45
55
public static final ConfigDef CONFIG_DEF =
@@ -48,7 +58,7 @@ public class AuthenticatorConfig extends AbstractConfig {
48
58
PROVIDER_OPT ,
49
59
ConfigDef .Type .STRING ,
50
60
"None" ,
51
- ConfigDef .ValidString .in ("None" , "PLAIN" , "GSSAPI" ),
61
+ ConfigDef .ValidString .in ("None" , "PLAIN" , "GSSAPI" , "OIDC" ),
52
62
ConfigDef .Importance .HIGH ,
53
63
"Authentication provider" )
54
64
.define (
@@ -80,7 +90,43 @@ public class AuthenticatorConfig extends AbstractConfig {
80
90
ConfigDef .Type .STRING ,
81
91
"dse" ,
82
92
ConfigDef .Importance .HIGH ,
83
- "SASL service name to use for GSSAPI provider authentication" );
93
+ "SASL service name to use for GSSAPI provider authentication" )
94
+ .define (
95
+ OIDC_ISSUER_OPT ,
96
+ ConfigDef .Type .STRING ,
97
+ "" ,
98
+ ConfigDef .Importance .HIGH ,
99
+ "OIDC Authentication server url" )
100
+ .define (
101
+ OIDC_CLIENT_ID_OPT ,
102
+ ConfigDef .Type .STRING ,
103
+ "" ,
104
+ ConfigDef .Importance .HIGH ,
105
+ "OIDC Client Id to use for authentication" )
106
+ .define (
107
+ OIDC_CLIENT_SECRET_OPT ,
108
+ ConfigDef .Type .PASSWORD ,
109
+ "" ,
110
+ ConfigDef .Importance .HIGH ,
111
+ "OIDC Client Secret to use for authentication" )
112
+ .define (
113
+ OIDC_USE_TLS_OPT ,
114
+ ConfigDef .Type .BOOLEAN ,
115
+ true ,
116
+ ConfigDef .Importance .HIGH ,
117
+ "Set to false to disable TLS encrypted connections. Defaults to true." )
118
+ .define (
119
+ OIDC_TRUSTSTORE_PATH_OPT ,
120
+ ConfigDef .Type .STRING ,
121
+ "" ,
122
+ ConfigDef .Importance .HIGH ,
123
+ "Path to the truststore file containing the OIDC issuer's certificate." )
124
+ .define (
125
+ OIDC_TRUSTSTORE_PASSWORD_OPT ,
126
+ ConfigDef .Type .PASSWORD ,
127
+ null ,
128
+ ConfigDef .Importance .HIGH ,
129
+ "Truststore file password containing the OIDC issuer's certificate." );
84
130
85
131
@ Nullable private final Path keyTabPath ;
86
132
@@ -101,9 +147,28 @@ public AuthenticatorConfig(Map<String, String> authSettings) {
101
147
if (getService ().isEmpty ()) {
102
148
throw new ConfigException (SERVICE_OPT , "<empty>" , "is required" );
103
149
}
104
-
105
150
assertAccessibleFile (keyTabPath , KEYTAB_OPT );
106
151
}
152
+
153
+ if (provider == Provider .OIDC ) {
154
+ if (getString (OIDC_ISSUER_OPT ).isEmpty ()) {
155
+ throw new ConfigException (OIDC_ISSUER_OPT , "<empty>" , "is required" );
156
+ }
157
+
158
+ try {
159
+ new URI (getString (OIDC_ISSUER_OPT ));
160
+ } catch (URISyntaxException e ) {
161
+ throw new ConfigException (
162
+ OIDC_ISSUER_OPT , getString (OIDC_ISSUER_OPT ), "is not a valid URI: " + e .getMessage ());
163
+ }
164
+
165
+ if (getString (OIDC_CLIENT_ID_OPT ).isEmpty ()) {
166
+ throw new ConfigException (OIDC_CLIENT_ID_OPT , "<empty>" , "is required" );
167
+ }
168
+ if (getPassword (OIDC_CLIENT_SECRET_OPT ).value ().isEmpty ()) {
169
+ throw new ConfigException (OIDC_CLIENT_SECRET_OPT , "<empty>" , "is required" );
170
+ }
171
+ }
107
172
}
108
173
109
174
/**
@@ -139,6 +204,13 @@ private static Map<String, String> sanitizeAuthSettings(Map<String, String> auth
139
204
mutated .put (PRINCIPAL_OPT , getPrincipalFromKeyTab (keyTabPath .toString ()));
140
205
}
141
206
}
207
+
208
+ if ("OIDC" .equals (provider )) {
209
+ if (!mutated .containsKey (OIDC_USE_TLS_OPT ) || mutated .get (OIDC_USE_TLS_OPT ).isEmpty ()) {
210
+ mutated .put (OIDC_USE_TLS_OPT , "true" );
211
+ }
212
+ }
213
+
142
214
return ImmutableMap .<String , String >builder ().putAll (mutated ).build ();
143
215
}
144
216
@@ -191,7 +263,7 @@ public Provider getProvider() {
191
263
return Provider .valueOf (providerString );
192
264
} catch (IllegalArgumentException e ) {
193
265
throw new ConfigException (
194
- PROVIDER_OPT , providerString , "valid values are None, PLAIN, GSSAPI" );
266
+ PROVIDER_OPT , providerString , "valid values are None, PLAIN, GSSAPI, OIDC " );
195
267
}
196
268
}
197
269
@@ -216,6 +288,35 @@ public String getService() {
216
288
return getString (SERVICE_OPT );
217
289
}
218
290
291
+ public URI getOIDCIssuer () {
292
+ try {
293
+ return new URI (getString (OIDC_ISSUER_OPT ));
294
+ } catch (URISyntaxException e ) {
295
+ // This should never happen because we validate the URI in the constructor.
296
+ return null ;
297
+ }
298
+ }
299
+
300
+ public String getOIDCClientId () {
301
+ return getString (OIDC_CLIENT_ID_OPT );
302
+ }
303
+
304
+ public String getOIDCClientSecret () {
305
+ return getPassword (OIDC_CLIENT_SECRET_OPT ).value ();
306
+ }
307
+
308
+ public boolean getOIDCUseTLS () {
309
+ return getBoolean (OIDC_USE_TLS_OPT );
310
+ }
311
+
312
+ public Path getOIDCTruststorePath () {
313
+ return getFilePath (getString (OIDC_TRUSTSTORE_PATH_OPT ));
314
+ }
315
+
316
+ public Password getOIDCTruststorePassword () {
317
+ return getPassword (OIDC_TRUSTSTORE_PASSWORD_OPT );
318
+ }
319
+
219
320
@ Override
220
321
public String toString () {
221
322
return configToString (
@@ -226,12 +327,16 @@ public String toString() {
226
327
PASSWORD_OPT ,
227
328
KEYTAB_OPT ,
228
329
PRINCIPAL_OPT ,
229
- SERVICE_OPT );
330
+ SERVICE_OPT ,
331
+ OIDC_ISSUER_OPT ,
332
+ OIDC_CLIENT_ID_OPT ,
333
+ OIDC_CLIENT_SECRET_OPT );
230
334
}
231
335
232
336
public enum Provider {
233
337
None ,
234
338
PLAIN ,
235
- GSSAPI
339
+ GSSAPI ,
340
+ OIDC
236
341
}
237
342
}
0 commit comments