From 7601d11a7ad794f0b18cdbdf66f34b7665298361 Mon Sep 17 00:00:00 2001 From: Andrei Kurosh Date: Sun, 14 May 2023 09:58:57 +0300 Subject: [PATCH] UseDefaultCredentials options for WebSockets proxy configuration. (#1734) --- .github/workflows/ReleaseNotes.md | 1 + .../Options/MqttClientWebSocketOptions.cs | 22 ++++++++++++++-- .../MqttClientWebSocketProxyOptions.cs | 2 ++ .../Implementations/MqttWebSocketChannel.cs | 26 ++++++++++++++++--- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ReleaseNotes.md b/.github/workflows/ReleaseNotes.md index fae4c230..835f5477 100644 --- a/.github/workflows/ReleaseNotes.md +++ b/.github/workflows/ReleaseNotes.md @@ -3,6 +3,7 @@ * [Core] Exposed more details of DISCONNECT packet in log (#1729). * [Client] Added overloads for setting packet payload and will payload (#1720). * [Client] The proper connect result is now exposed in the _Disconnected_ event when authentication fails (#1139). +* [Client] Exposed _UseDefaultCredentials_ and more for Web Socket options and proxy options (#1734, thanks to @impworks). * [Client] Exposed more TLS options (#1729). * [Client] Fixed wrong return code conversion (#1729). * [Server] Improved performance by changing internal locking strategy for subscriptions (#1716, thanks to @zeheng). diff --git a/Source/MQTTnet/Client/Options/MqttClientWebSocketOptions.cs b/Source/MQTTnet/Client/Options/MqttClientWebSocketOptions.cs index e9de2da8..0b386675 100644 --- a/Source/MQTTnet/Client/Options/MqttClientWebSocketOptions.cs +++ b/Source/MQTTnet/Client/Options/MqttClientWebSocketOptions.cs @@ -2,15 +2,19 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Net; +using System.Net.WebSockets; namespace MQTTnet.Client { public sealed class MqttClientWebSocketOptions : IMqttClientChannelOptions { public CookieContainer CookieContainer { get; set; } - + + public ICredentials Credentials { get; set; } + public MqttClientWebSocketProxyOptions ProxyOptions { get; set; } public IDictionary RequestHeaders { get; set; } @@ -18,12 +22,26 @@ namespace MQTTnet.Client public ICollection SubProtocols { get; set; } = new List { "mqtt" }; public MqttClientTlsOptions TlsOptions { get; set; } = new MqttClientTlsOptions(); - + public string Uri { get; set; } public override string ToString() { return Uri; } + +#if !NETSTANDARD1_3 + /// + /// Gets or sets the keep alive interval for the Web Socket connection. + /// This is not related to the keep alive interval for the MQTT protocol. + /// + public TimeSpan KeepAliveInterval { get; set; } = WebSocket.DefaultKeepAliveInterval; + + /// + /// Gets or sets whether the default (system) credentials should be used when connecting via Web Socket connection. + /// This is not related to the credentials which are used for the MQTT protocol. + /// + public bool UseDefaultCredentials { get; set; } +#endif } } \ No newline at end of file diff --git a/Source/MQTTnet/Client/Options/MqttClientWebSocketProxyOptions.cs b/Source/MQTTnet/Client/Options/MqttClientWebSocketProxyOptions.cs index 92968984..3381109e 100644 --- a/Source/MQTTnet/Client/Options/MqttClientWebSocketProxyOptions.cs +++ b/Source/MQTTnet/Client/Options/MqttClientWebSocketProxyOptions.cs @@ -16,6 +16,8 @@ namespace MQTTnet.Client public bool BypassOnLocal { get; set; } + public bool UseDefaultCredentials { get; set; } + public string[] BypassList { get; set; } } } \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs index fbabd51d..900b292b 100644 --- a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs +++ b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs @@ -155,14 +155,26 @@ namespace MQTTnet.Implementations throw new NotSupportedException("Proxies are not supported when using 'netstandard 1.3'."); #else var proxyUri = new Uri(_options.ProxyOptions.Address); - + WebProxy webProxy; + if (!string.IsNullOrEmpty(_options.ProxyOptions.Username) && !string.IsNullOrEmpty(_options.ProxyOptions.Password)) { var credentials = new NetworkCredential(_options.ProxyOptions.Username, _options.ProxyOptions.Password, _options.ProxyOptions.Domain); - return new WebProxy(proxyUri, _options.ProxyOptions.BypassOnLocal, _options.ProxyOptions.BypassList, credentials); + webProxy = new WebProxy(proxyUri, _options.ProxyOptions.BypassOnLocal, _options.ProxyOptions.BypassList, credentials); + } + else + { + webProxy = new WebProxy(proxyUri, _options.ProxyOptions.BypassOnLocal, _options.ProxyOptions.BypassList); + } + + if (_options.ProxyOptions.UseDefaultCredentials) + { + // Only update the property if required because setting it to false will alter + // the used credentials internally! + webProxy.UseDefaultCredentials = true; } - return new WebProxy(proxyUri, _options.ProxyOptions.BypassOnLocal, _options.ProxyOptions.BypassList); + return webProxy; #endif } @@ -206,7 +218,13 @@ namespace MQTTnet.Implementations #endif } } - + +#if !NETSTANDARD1_3 + clientWebSocket.Options.UseDefaultCredentials = _options.UseDefaultCredentials; + clientWebSocket.Options.KeepAliveInterval = _options.KeepAliveInterval; +#endif + clientWebSocket.Options.Credentials = _options.Credentials; + var certificateValidationHandler = _options.TlsOptions?.CertificateValidationHandler; if (certificateValidationHandler != null) {