Skip to content

Commit e072176

Browse files
authored
added SchemaRegistryConfigBasicAuthCredentialsSource (#728)
* added SchemaRegistryConfigBasicAuthCredentialsSource * review changes * actually ran the integration tests this time * badly formatted xml comment fix
1 parent cd0586c commit e072176

File tree

3 files changed

+85
-31
lines changed

3 files changed

+85
-31
lines changed

src/Confluent.SchemaRegistry/CachedSchemaRegistryClient.cs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,29 +81,22 @@ public CachedSchemaRegistryClient(IEnumerable<KeyValuePair<string, string>> conf
8181
// Convert.ToString returns "" in the null case here.
8282
var basicAuthSource = Convert.ToString(config.FirstOrDefault(prop => prop.Key.ToLower() == SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthCredentialsSource).Value);
8383
var basicAuthInfo = Convert.ToString(config.FirstOrDefault(prop => prop.Key.ToLower() == SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthUserInfo).Value);
84-
if (basicAuthInfo != "" && basicAuthSource == "")
85-
{
86-
// default to USER_INFO if no source specified, since the strongly typed config
87-
// class doesn't even expose the config source property.
88-
basicAuthSource = "USER_INFO";
89-
}
9084

9185
string username = null;
9286
string password = null;
9387

94-
if (basicAuthSource == "USER_INFO")
88+
if (basicAuthSource == "USER_INFO" || basicAuthSource == "")
9589
{
96-
if (basicAuthInfo == "")
97-
{
98-
throw new ArgumentException($"CachedSchemaRegistryClient: {SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthCredentialsSource} set to 'USER_INFO', but no value specified for {SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthUserInfo}.");
99-
}
100-
var userPass = (basicAuthInfo).Split(':');
101-
if (userPass.Length != 2)
90+
if (basicAuthInfo != "")
10291
{
103-
throw new ArgumentException($"CachedSchemaRegistryClient: Configuration property {SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthUserInfo} must be of the form 'username:password'.");
92+
var userPass = (basicAuthInfo).Split(':');
93+
if (userPass.Length != 2)
94+
{
95+
throw new ArgumentException($"CachedSchemaRegistryClient: Configuration property {SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthUserInfo} must be of the form 'username:password'.");
96+
}
97+
username = userPass[0];
98+
password = userPass[1];
10499
}
105-
username = userPass[0];
106-
password = userPass[1];
107100
}
108101
else if (basicAuthSource == "SASL_INHERIT")
109102
{
@@ -126,7 +119,7 @@ public CachedSchemaRegistryClient(IEnumerable<KeyValuePair<string, string>> conf
126119
}
127120
else
128121
{
129-
// no basic auth info.
122+
throw new ArgumentException($"CachedSchemaRegistryClient: Invalid value '{basicAuthSource}' specified for property '{SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthCredentialsSource}'");
130123
}
131124

132125
foreach (var property in config)
@@ -136,8 +129,8 @@ public CachedSchemaRegistryClient(IEnumerable<KeyValuePair<string, string>> conf
136129
continue;
137130
}
138131

139-
if (property.Key != SchemaRegistryConfig.PropertyNames.SchemaRegistryUrl &&
140-
property.Key != SchemaRegistryConfig.PropertyNames.SchemaRegistryRequestTimeoutMs &&
132+
if (property.Key != SchemaRegistryConfig.PropertyNames.SchemaRegistryUrl &&
133+
property.Key != SchemaRegistryConfig.PropertyNames.SchemaRegistryRequestTimeoutMs &&
141134
property.Key != SchemaRegistryConfig.PropertyNames.SchemaRegistryMaxCachedSchemas &&
142135
property.Key != SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthCredentialsSource &&
143136
property.Key != SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthUserInfo)

src/Confluent.SchemaRegistry/SchemaRegistryConfig.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,30 @@
1414
//
1515
// Refer to LICENSE for more information.
1616

17+
using System;
1718
using System.Collections;
1819
using System.Collections.Generic;
1920

2021

2122
namespace Confluent.SchemaRegistry
2223
{
24+
/// <summary>
25+
/// Auth credentials source.
26+
/// </summary>
27+
public enum AuthCredentialsSource
28+
{
29+
/// <summary>
30+
/// Credentials are specified via the `schema.registry.basic.auth.user.info` config property in the form username:password.
31+
/// If `schema.registry.basic.auth.user.info` is not set, authentication is disabled.
32+
/// </summary>
33+
UserInfo,
34+
35+
/// <summary>
36+
/// Credentials are specified via the `sasl.username` and `sasl.password` configuration properties.
37+
/// </summary>
38+
SaslInherit
39+
}
40+
2341
/// <summary>
2442
/// <see cref="CachedSchemaRegistryClient" /> configuration properties.
2543
/// </summary>
@@ -53,15 +71,44 @@ public static class PropertyNames
5371

5472
/// <summary>
5573
/// Specifies the configuration property(ies) that provide the basic authentication credentials.
74+
/// USER_INFO: Credentials are specified via the `schema.registry.basic.auth.user.info` config property in the form username:password.
75+
/// If `schema.registry.basic.auth.user.info` is not set, authentication is disabled.
76+
/// SASL_INHERIT: Credentials are specified via the `sasl.username` and `sasl.password` configuration properties.
77+
///
78+
/// default: USER_INFO
5679
/// </summary>
5780
public const string SchemaRegistryBasicAuthCredentialsSource = "schema.registry.basic.auth.credentials.source";
5881

5982
/// <summary>
6083
/// Basic auth credentials in the form {username}:{password}.
84+
///
85+
/// default: "" (no authentication).
6186
/// </summary>
6287
public const string SchemaRegistryBasicAuthUserInfo = "schema.registry.basic.auth.user.info";
6388
}
6489

90+
/// <summary>
91+
/// Specifies the configuration property(ies) that provide the basic authentication credentials.
92+
/// </summary>
93+
public AuthCredentialsSource? SchemaRegistryBasicAuthCredentialsSource
94+
{
95+
get
96+
{
97+
var r = Get(PropertyNames.SchemaRegistryBasicAuthCredentialsSource);
98+
if (r == null) { return null; }
99+
if (r == "USER_INFO") { return AuthCredentialsSource.UserInfo; }
100+
if (r == "SASL_INHERIT") { return AuthCredentialsSource.SaslInherit; }
101+
throw new ArgumentException($"Unknown ${PropertyNames.SchemaRegistryBasicAuthCredentialsSource} value: {r}.");
102+
}
103+
set
104+
{
105+
if (value == null) { this.properties.Remove(PropertyNames.SchemaRegistryBasicAuthCredentialsSource); }
106+
else if (value == AuthCredentialsSource.UserInfo) { this.properties[PropertyNames.SchemaRegistryBasicAuthCredentialsSource] = "USER_INFO"; }
107+
else if (value == AuthCredentialsSource.SaslInherit) { this.properties[PropertyNames.SchemaRegistryBasicAuthCredentialsSource] = "SASL_INHERIT"; }
108+
else { throw new NotImplementedException($"Unknown ${PropertyNames.SchemaRegistryBasicAuthCredentialsSource} value: {value}."); }
109+
}
110+
}
111+
65112
/// <summary>
66113
/// A comma-separated list of URLs for schema registry instances that are
67114
/// used to register or lookup schemas.

test/Confluent.SchemaRegistry.IntegrationTests/Tests/BasicAuth.cs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,18 @@ public static void BasicAuth(Config config)
3636
// 1. valid configuration cases
3737

3838
// 1.1. credentials specified as USER_INFO.
39-
var conf = new Dictionary<string, string>
40-
{
41-
{ "schema.registry.url", config.ServerWithAuth },
42-
{ "schema.registry.basic.auth.credentials.source", "USER_INFO" },
43-
{ "schema.registry.basic.auth.user.info", $"{config.Username}:{config.Password}" }
39+
var conf = new SchemaRegistryConfig
40+
{
41+
SchemaRegistryUrl = config.ServerWithAuth,
42+
SchemaRegistryBasicAuthCredentialsSource = AuthCredentialsSource.UserInfo,
43+
SchemaRegistryBasicAuthUserInfo = $"{config.Username}:{config.Password}"
4444
};
45+
46+
// some sanity checking of strongly typed config property name mappings.
47+
Assert.Equal(config.ServerWithAuth, conf.Get("schema.registry.url"));
48+
Assert.Equal("USER_INFO", conf.Get("schema.registry.basic.auth.credentials.source"));
49+
Assert.Equal($"{config.Username}:{config.Password}", conf.Get("schema.registry.basic.auth.user.info"));
50+
4551
using (var sr = new CachedSchemaRegistryClient(conf))
4652
{
4753
var topicName = Guid.NewGuid().ToString();
@@ -85,7 +91,7 @@ public static void BasicAuth(Config config)
8591

8692
// 1.4. credentials specified as SASL_INHERIT via strongly typed config.
8793
var conf3 = new SchemaRegistryConfig { SchemaRegistryUrl = config.ServerWithAuth };
88-
conf3.Set(SchemaRegistryConfig.PropertyNames.SchemaRegistryBasicAuthCredentialsSource, "SASL_INHERIT");
94+
conf3.SchemaRegistryBasicAuthCredentialsSource = AuthCredentialsSource.SaslInherit;
8995
conf3.Set("sasl.username", config.Username);
9096
conf3.Set("sasl.password", config.Password);
9197
using (var sr = new CachedSchemaRegistryClient(conf3))
@@ -110,15 +116,23 @@ public static void BasicAuth(Config config)
110116
});
111117
});
112118

113-
Assert.Throws<ArgumentException>(() =>
114-
{
119+
Assert.Throws<ArgumentException>(() =>
120+
{
115121
var sr = new CachedSchemaRegistryClient(new Dictionary<string, string>
116122
{
117123
{ "schema.registry.url", config.ServerWithAuth },
118-
{ "schema.registry.basic.auth.credentials.source", "USER_INFO" },
119-
{ "sasl.username", config.Username },
120-
{ "sasl.password", config.Password }
121-
});
124+
{ "schema.registry.basic.auth.credentials.source", "UBUTE_SOURCE" }
125+
});
126+
});
127+
128+
Assert.Throws<ArgumentException>(() =>
129+
{
130+
var sr = new CachedSchemaRegistryClient(new Dictionary<string, string>
131+
{
132+
{ "schema.registry.url", config.ServerWithAuth },
133+
{ "schema.registry.basic.auth.credentials.source", "NONE" },
134+
{ "schema.registry.basic.auth.user.info", $"{config.Username:config.Password}" }
135+
});
122136
});
123137

124138
// connect to authenticating without credentials. shouldn't work.

0 commit comments

Comments
 (0)