Skip to content

Commit 3afa08b

Browse files
terencefanvicancy
andauthored
Release 1.18 (#1621)
* code cleanup before refactor parser (#1617) * Add authtypes (azure, azure.msi, azure.app) (#1616) * Promote client connection trace to info (#1620) Co-authored-by: Liangying.Wei <[email protected]>
1 parent 5d6662c commit 3afa08b

File tree

3 files changed

+188
-90
lines changed

3 files changed

+188
-90
lines changed

src/Microsoft.Azure.SignalR.Common/Utilities/ConnectionStringParser.cs

Lines changed: 113 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,69 +11,81 @@ namespace Microsoft.Azure.SignalR
1111
internal static class ConnectionStringParser
1212
{
1313
private const string AccessKeyProperty = "accesskey";
14+
1415
private const string AuthTypeProperty = "authtype";
16+
1517
private const string ClientCertProperty = "clientCert";
16-
private const string ClientEndpointProperty = "ClientEndpoint";
18+
19+
private const string ClientEndpointProperty = "clientEndpoint";
20+
1721
private const string ClientIdProperty = "clientId";
22+
1823
private const string ClientSecretProperty = "clientSecret";
24+
1925
private const string EndpointProperty = "endpoint";
20-
private const string ServerEndpoint = "ServerEndpoint";
26+
2127
private const string InvalidVersionValueFormat = "Version {0} is not supported.";
28+
2229
private const string PortProperty = "port";
30+
31+
private const string ServerEndpoint = "ServerEndpoint";
32+
2333
// For SDK 1.x, only support Azure SignalR Service 1.x
2434
private const string SupportedVersion = "1";
2535

2636
private const string TenantIdProperty = "tenantId";
37+
38+
private const string TypeAzure = "azure";
39+
40+
private const string TypeAzureAD = "aad";
41+
42+
private const string TypeAzureApp = "azure.app";
43+
44+
private const string TypeAzureMsi = "azure.msi";
45+
2746
private const string ValidVersionRegex = "^" + SupportedVersion + @"\.\d+(?:[\w-.]+)?$";
47+
2848
private const string VersionProperty = "version";
29-
private static readonly string InvalidPortValue = $"Invalid value for {PortProperty} property.";
49+
50+
private static readonly string InvalidClientEndpointProperty = $"Invalid value for {ClientEndpointProperty} property, it must be a valid URI.";
51+
52+
private static readonly string InvalidEndpointProperty = $"Invalid value for {EndpointProperty} property, it must be a valid URI.";
53+
54+
private static readonly string InvalidPortValue = $"Invalid value for {PortProperty} property, it must be an positive integer between (0, 65536)";
3055

3156
private static readonly char[] KeyValueSeparator = { '=' };
3257

3358
private static readonly string MissingAccessKeyProperty =
3459
$"{AccessKeyProperty} is required.";
3560

61+
private static readonly string MissingClientIdProperty =
62+
$"Connection string missing required properties {ClientIdProperty}.";
63+
3664
private static readonly string MissingClientSecretProperty =
3765
$"Connection string missing required properties {ClientSecretProperty} or {ClientCertProperty}.";
3866

3967
private static readonly string MissingEndpointProperty =
4068
$"Connection string missing required properties {EndpointProperty}.";
4169

70+
private static readonly string MissingTenantIdProperty =
71+
$"Connection string missing required properties {TenantIdProperty}.";
72+
4273
private static readonly char[] PropertySeparator = { ';' };
4374

4475
internal static ParsedConnectionString Parse(string connectionString)
4576
{
46-
var properties = connectionString.Split(PropertySeparator, StringSplitOptions.RemoveEmptyEntries);
47-
if (properties.Length < 2)
48-
{
49-
throw new ArgumentException(MissingEndpointProperty, nameof(connectionString));
50-
}
51-
52-
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
53-
foreach (var property in properties)
54-
{
55-
var kvp = property.Split(KeyValueSeparator, 2);
56-
if (kvp.Length != 2) continue;
57-
58-
var key = kvp[0].Trim();
59-
if (dict.ContainsKey(key))
60-
{
61-
throw new ArgumentException($"Duplicate properties found in connection string: {key}.");
62-
}
63-
64-
dict.Add(key, kvp[1].Trim());
65-
}
77+
var dict = ToDictionary(connectionString);
6678

6779
// parse and validate endpoint.
6880
if (!dict.TryGetValue(EndpointProperty, out var endpoint))
6981
{
70-
throw new ArgumentException(MissingEndpointProperty, nameof(connectionString));
82+
throw new ArgumentException(MissingEndpointProperty, nameof(endpoint));
7183
}
7284
endpoint = endpoint.TrimEnd('/');
7385

7486
if (!TryGetEndpointUri(endpoint, out var endpointUri))
7587
{
76-
throw new ArgumentException($"Endpoint property in connection string is not a valid URI: {dict[EndpointProperty]}.");
88+
throw new ArgumentException(InvalidEndpointProperty, nameof(endpoint));
7789
}
7890
var builder = new UriBuilder(endpointUri);
7991

@@ -83,38 +95,43 @@ internal static ParsedConnectionString Parse(string connectionString)
8395
{
8496
if (!Regex.IsMatch(v, ValidVersionRegex))
8597
{
86-
throw new ArgumentException(string.Format(InvalidVersionValueFormat, v), nameof(connectionString));
98+
throw new ArgumentException(string.Format(InvalidVersionValueFormat, v), nameof(version));
8799
}
88100
version = v;
89101
}
90102

91103
// parse and validate port.
92104
if (dict.TryGetValue(PortProperty, out var s))
93105
{
94-
if (int.TryParse(s, out var p) && p > 0 && p <= 0xFFFF)
106+
if (int.TryParse(s, out var port) && port > 0 && port <= 0xFFFF)
95107
{
96-
builder.Port = p;
108+
builder.Port = port;
97109
}
98110
else
99111
{
100-
throw new ArgumentException(InvalidPortValue, nameof(connectionString));
112+
throw new ArgumentException(InvalidPortValue, nameof(port));
101113
}
102114
}
103115

104116
Uri clientEndpointUri = null;
117+
105118
// parse and validate clientEndpoint.
106119
if (dict.TryGetValue(ClientEndpointProperty, out var clientEndpoint))
107120
{
108121
if (!TryGetEndpointUri(clientEndpoint, out clientEndpointUri))
109122
{
110-
throw new ArgumentException($"{ClientEndpointProperty} property in connection string is not a valid URI: {clientEndpoint}.");
123+
throw new ArgumentException(InvalidClientEndpointProperty, nameof(clientEndpoint));
111124
}
112125
}
113126

127+
// try building accesskey.
114128
dict.TryGetValue(AuthTypeProperty, out var type);
115129
var accessKey = type?.ToLower() switch
116130
{
117-
"aad" => BuildAadAccessKey(builder.Uri, dict),
131+
TypeAzureAD => BuildAadAccessKey(builder.Uri, dict),
132+
TypeAzure => BuildAzureAccessKey(builder.Uri, dict),
133+
TypeAzureApp => BuildAzureAppAccessKey(builder.Uri, dict),
134+
TypeAzureMsi => BuildAzureMsiAccessKey(builder.Uri, dict),
118135
_ => BuildAccessKey(builder.Uri, dict),
119136
};
120137

@@ -180,5 +197,70 @@ private static AccessKey BuildAccessKey(Uri uri, Dictionary<string, string> dict
180197
}
181198
throw new ArgumentException(MissingAccessKeyProperty, AccessKeyProperty);
182199
}
200+
201+
private static AccessKey BuildAzureAccessKey(Uri uri, Dictionary<string, string> dict)
202+
{
203+
return new AadAccessKey(uri, new DefaultAzureCredential());
204+
}
205+
206+
private static AccessKey BuildAzureAppAccessKey(Uri uri, Dictionary<string, string> dict)
207+
{
208+
if (!dict.TryGetValue(ClientIdProperty, out var clientId))
209+
{
210+
throw new ArgumentException(MissingClientIdProperty, ClientIdProperty);
211+
}
212+
213+
if (!dict.TryGetValue(TenantIdProperty, out var tenantId))
214+
{
215+
throw new ArgumentException(MissingTenantIdProperty, TenantIdProperty);
216+
}
217+
218+
if (dict.TryGetValue(ClientSecretProperty, out var clientSecret))
219+
{
220+
return new AadAccessKey(uri, new ClientSecretCredential(tenantId, clientId, clientSecret));
221+
}
222+
else if (dict.TryGetValue(ClientCertProperty, out var clientCertPath))
223+
{
224+
return new AadAccessKey(uri, new ClientCertificateCredential(tenantId, clientId, clientCertPath));
225+
}
226+
throw new ArgumentException(MissingClientSecretProperty, ClientSecretProperty);
227+
}
228+
229+
private static AccessKey BuildAzureMsiAccessKey(Uri uri, Dictionary<string, string> dict)
230+
{
231+
if (dict.TryGetValue(ClientIdProperty, out var clientId))
232+
{
233+
return new AadAccessKey(uri, new ManagedIdentityCredential(clientId));
234+
}
235+
return new AadAccessKey(uri, new ManagedIdentityCredential());
236+
}
237+
238+
private static Dictionary<string, string> ToDictionary(string connectionString)
239+
{
240+
var properties = connectionString.Split(PropertySeparator, StringSplitOptions.RemoveEmptyEntries);
241+
if (properties.Length < 2)
242+
{
243+
throw new ArgumentException(MissingEndpointProperty, nameof(connectionString));
244+
}
245+
246+
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
247+
foreach (var property in properties)
248+
{
249+
var kvp = property.Split(KeyValueSeparator, 2);
250+
if (kvp.Length != 2)
251+
{
252+
continue;
253+
}
254+
255+
var key = kvp[0].Trim();
256+
if (dict.ContainsKey(key))
257+
{
258+
throw new ArgumentException($"Duplicate properties found in connection string: {key}.");
259+
}
260+
261+
dict.Add(key, kvp[1].Trim());
262+
}
263+
return dict;
264+
}
183265
}
184266
}

src/Microsoft.Azure.SignalR/ServerConnections/ServiceConnection.Log.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ private static class Log
4646
LoggerMessage.Define<ulong?, string>(LogLevel.Warning, new EventId(10, "ReceivedMessageForNonExistentConnection"), "Received message {tracingId} for connection {TransportConnectionId} which does not exist.");
4747

4848
private static readonly Action<ILogger, string, Exception> _connectedStarting =
49-
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(11, "ConnectedStarting"), "Connection {TransportConnectionId} started.");
49+
LoggerMessage.Define<string>(LogLevel.Information, new EventId(11, "ConnectedStarting"), "Connection {TransportConnectionId} started.");
5050

5151
private static readonly Action<ILogger, string, Exception> _connectedEnding =
52-
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(12, "ConnectedEnding"), "Connection {TransportConnectionId} ended.");
52+
LoggerMessage.Define<string>(LogLevel.Information, new EventId(12, "ConnectedEnding"), "Connection {TransportConnectionId} ended.");
5353

5454
private static readonly Action<ILogger, string, Exception> _closeConnection =
5555
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(13, "CloseConnection"), "Sending close connection message to the service for {TransportConnectionId}.");

0 commit comments

Comments
 (0)