Browse Source

Support using Process.Start() on macOS and reintroduce the runtime checks preventing the portable version of OpenIddict.Client.SystemIntegration from being used on Android, iOS and Mac Catalyst

pull/2338/head
Kévin Chalet 1 year ago
parent
commit
c887672c4a
  1. 2
      sandbox/OpenIddict.Sandbox.WinForms.Client/Worker.cs
  2. 2
      sandbox/OpenIddict.Sandbox.Wpf.Client/Worker.cs
  3. 7
      src/OpenIddict.Abstractions/OpenIddictResources.resx
  4. 18
      src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationBuilder.cs
  5. 19
      src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs
  6. 19
      src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs
  7. 33
      src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs
  8. 33
      src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs
  9. 46
      src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs
  10. 2
      src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHttpListener.cs

2
sandbox/OpenIddict.Sandbox.WinForms.Client/Worker.cs

@ -27,7 +27,7 @@ public class Worker : IHostedService
// in HKEY_CLASSES_ROOT (in this case, it should be added by a dedicated installer).
//
// Alternatively, the application can be packaged and use windows.protocol to
// register the protocol handler/custom URI scheme with the operation system.
// register the protocol handler/custom URI scheme with the operating system.
using var root = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Classes\\com.openiddict.sandbox.winforms.client");
root.SetValue(string.Empty, "URL:com.openiddict.sandbox.winforms.client");
root.SetValue("URL Protocol", string.Empty);

2
sandbox/OpenIddict.Sandbox.Wpf.Client/Worker.cs

@ -27,7 +27,7 @@ public class Worker : IHostedService
// in HKEY_CLASSES_ROOT (in this case, it should be added by a dedicated installer).
//
// Alternatively, the application can be packaged and use windows.protocol to
// register the protocol handler/custom URI scheme with the operation system.
// register the protocol handler/custom URI scheme with the operating system.
using var root = Registry.CurrentUser.CreateSubKey("SOFTWARE\\Classes\\com.openiddict.sandbox.wpf.client");
root.SetValue(string.Empty, "URL:com.openiddict.sandbox.wpf.client");
root.SetValue("URL Protocol", string.Empty);

7
src/OpenIddict.Abstractions/OpenIddictResources.resx

@ -1560,7 +1560,7 @@ To apply post-logout redirection responses, create a class implementing 'IOpenId
<value>An explicit grant type must be attached when specifying a specific response type (except when using the special response_type=none value).</value>
</data>
<data name="ID0446" xml:space="preserve">
<value>AS web authentication sessions are only supported on iOS 12.0+/macOS 10.15+/Mac Catalyst 12.0+ and require using an OS-specific target framework moniker (e.g on macOS, 'net8.0-macos15.0').</value>
<value>AS web authentication sessions are only supported on iOS 12.0+/macOS 10.15+/Mac Catalyst 12.0+ and require using an OS-specific target framework moniker on macOS (e.g 'net8.0-macos15.0').</value>
</data>
<data name="ID0447" xml:space="preserve">
<value>The current UI window cannot be resolved.</value>
@ -1569,8 +1569,7 @@ To apply post-logout redirection responses, create a class implementing 'IOpenId
<value>An unknown error occurred while trying to start an AS web authentication session.</value>
</data>
<data name="ID0449" xml:space="preserve">
<value>The generic version of the OpenIddict.Client.SystemIntegration package cannot be used on this platform. Make sure your application is referencing the correct version by using the appropriate OS-specific TFM (e.g on macOS, 'net8.0-macos10.15').</value>
<comment>This resource is no longer used and will be removed in a future version.</comment>
<value>The portable version of the OpenIddict.Client.SystemIntegration package cannot be used on Android, iOS and Mac Catalyst. Make sure your application is referencing the correct version by using the appropriate OS-specific TFM (e.g on iOS, 'net8.0-ios18.0').</value>
</data>
<data name="ID0450" xml:space="preserve">
<value>An HTTP redirect_uri or post_logout_redirect_uri cannot be used when using AS web authentication sessions. Make sure you're using a custom protocol scheme for all the callback URIs attached to the client registration. Alternatively, you can register an associated domain and use an HTTPS redirect_uri or post_logout_redirect_uri pointing to that domain (supported only on iOS 17.4+, Mac Catalyst 17.4+ and macOS 14.4+).</value>
@ -1579,7 +1578,7 @@ To apply post-logout redirection responses, create a class implementing 'IOpenId
<value>The Zoho integration requires sending the region of the server when using the client credentials or refresh token grants. For that, attach a ".location" authentication property containing the region to use.</value>
</data>
<data name="ID0452" xml:space="preserve">
<value>Custom tabs intents are only supported on Android and require using an OS-specific target framework moniker (e.g 'net8.0-android34.0').</value>
<value>Custom tabs intents are only supported on Android.</value>
</data>
<data name="ID0453" xml:space="preserve">
<value>The specified intent doesn't contain a valid data URI.</value>

18
src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationBuilder.cs

@ -121,7 +121,7 @@ public sealed class OpenIddictClientSystemIntegrationBuilder
/// <returns>The <see cref="OpenIddictClientSystemIntegrationBuilder"/>.</returns>
public OpenIddictClientSystemIntegrationBuilder SetAllowedEmbeddedWebServerPorts(params int[] ports)
{
if (Array.Exists(ports, static port => port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort))
if (Array.Exists(ports, static port => port is < IPEndPoint.MinPort or > IPEndPoint.MaxPort))
{
throw new ArgumentOutOfRangeException(nameof(ports));
}
@ -278,25 +278,15 @@ public sealed class OpenIddictClientSystemIntegrationBuilder
return Configure(options => options.PipeSecurity = security);
}
/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><see langword="true"/> if the specified object is equal to the current object; otherwise, false.</returns>
/// <inheritdoc/>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Serves as the default hash function.
/// </summary>
/// <returns>A hash code for the current object.</returns>
/// <inheritdoc/>
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() => base.GetHashCode();
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
/// <inheritdoc/>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string? ToString() => base.ToString();
}

19
src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs

@ -83,6 +83,25 @@ public sealed class OpenIddictClientSystemIntegrationConfiguration : IConfigureO
throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389));
}
#if !SUPPORTS_ANDROID
// When running on Android, iOS or Mac Catalyst, ensure the version compiled for these platforms
// is used to prevent the generic/non-OS specific TFM from being used as launching the system
// browser cannot be done using Process.Start() and requires using OS-specific APIs that are
// not available on the portable version of the OpenIddict.Client.SystemIntegration package.
if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("android")))
{
throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449));
}
#endif
#if !SUPPORTS_UIKIT
if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst")))
{
throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449));
}
#endif
#if SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON
// Ensure the operating system version is supported.
if ((OperatingSystem.IsAndroid() && !OperatingSystem.IsAndroidVersionAtLeast(21)) ||

19
src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs

@ -42,6 +42,25 @@ public static class OpenIddictClientSystemIntegrationExtensions
throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389));
}
#if !SUPPORTS_ANDROID
// When running on Android, iOS or Mac Catalyst, ensure the version compiled for these platforms
// is used to prevent the generic/non-OS specific TFM from being used as launching the system
// browser cannot be done using Process.Start() and requires using OS-specific APIs that are
// not available on the portable version of the OpenIddict.Client.SystemIntegration package.
if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("android")))
{
throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449));
}
#endif
#if !SUPPORTS_UIKIT
if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst")))
{
throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449));
}
#endif
#if SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON
// Ensure the operating system version is supported.
if ((OperatingSystem.IsAndroid() && !OperatingSystem.IsAndroidVersionAtLeast(21)) ||

33
src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs

@ -5,7 +5,6 @@
*/
using System.Collections.Immutable;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
@ -106,8 +105,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION
if (string.IsNullOrEmpty(context.RedirectUri) ||
!Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out Uri? uri))
@ -239,7 +236,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
NSUrl CreateUrl() => new(OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value)).AbsoluteUri);
@ -331,8 +328,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
#if SUPPORTS_ANDROID && SUPPORTS_ANDROIDX_BROWSER
if (string.IsNullOrEmpty(context.RedirectUri))
{
@ -359,7 +354,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
// custom activity responsible for handling callback URIs pointing to a custom scheme.
intent.LaunchUrl(Application.Context, NativeUri.Parse(OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value)).AbsoluteUri)!);
@ -404,8 +399,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
#if SUPPORTS_WINDOWS_RUNTIME
if (string.IsNullOrEmpty(context.RedirectUri))
{
@ -444,7 +437,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
options : WebAuthenticationOptions.None,
requestUri : OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value)),
callbackUri: new Uri(context.RedirectUri, UriKind.Absolute)))
@ -551,11 +544,9 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
var uri = OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value));
@ -594,6 +585,8 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
}
}
// On Android, iOS and Mac Catalyst, Process.Start() is not supported and
// OS-specific/non-portable APIs must be used to launch the system browser.
#if SUPPORTS_ANDROID
if (OperatingSystem.IsAndroid() && TryLaunchBrowserWithGenericIntent(uri))
{
@ -601,20 +594,26 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
return;
}
#endif
#if SUPPORTS_UIKIT
if ((OperatingSystem.IsIOS() || OperatingSystem.IsMacCatalyst()) && await TryLaunchBrowserWithUIApplicationAsync(uri))
{
context.HandleRequest();
return;
}
#elif SUPPORTS_APPKIT
#endif
#if SUPPORTS_APPKIT
if (OperatingSystem.IsMacOS() && TryLaunchBrowserWithNSWorkspace(uri))
{
context.HandleRequest();
return;
}
#endif
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && await TryLaunchBrowserWithOpenAsync(uri))
{
context.HandleRequest();
return;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && await TryLaunchBrowserWithXdgOpenAsync(uri))
{
context.HandleRequest();
@ -650,8 +649,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response is not null, SR.GetResourceString(SR.ID4007));
// This handler only applies to HTTP listener requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpListenerContext()?.Response ??
@ -663,7 +660,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
// Return a message indicating whether the authentication process
// succeeded or failed and that will be visible by the user.
var buffer = Encoding.UTF8.GetBytes(context.Transaction.Response.Error switch
var buffer = Encoding.UTF8.GetBytes(context.Response.Error switch
{
null or { Length: 0 } => "Login completed. Please return to the application.",
Errors.AccessDenied => "Authorization denied. Please return to the application.",

33
src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs

@ -5,7 +5,6 @@
*/
using System.Collections.Immutable;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
@ -106,8 +105,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION
if (string.IsNullOrEmpty(context.PostLogoutRedirectUri) ||
!Uri.TryCreate(context.PostLogoutRedirectUri, UriKind.Absolute, out Uri? uri))
@ -239,7 +236,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
NSUrl CreateUrl() => new(OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value)).AbsoluteUri);
@ -331,8 +328,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
#if SUPPORTS_ANDROID && SUPPORTS_ANDROIDX_BROWSER
if (string.IsNullOrEmpty(context.PostLogoutRedirectUri))
{
@ -359,7 +354,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
// custom activity responsible for handling callback URIs pointing to a custom scheme.
intent.LaunchUrl(Application.Context, NativeUri.Parse(OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value)).AbsoluteUri)!);
@ -404,8 +399,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
#if SUPPORTS_WINDOWS_RUNTIME
if (string.IsNullOrEmpty(context.PostLogoutRedirectUri))
{
@ -444,7 +437,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
options : WebAuthenticationOptions.None,
requestUri : OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value)),
callbackUri: new Uri(context.PostLogoutRedirectUri, UriKind.Absolute)))
@ -551,11 +544,9 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008));
var uri = OpenIddictHelpers.AddQueryStringParameters(
uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute),
parameters: context.Transaction.Request.GetParameters().ToDictionary(
parameters: context.Request.GetParameters().ToDictionary(
static parameter => parameter.Key,
static parameter => (StringValues) parameter.Value));
@ -594,6 +585,8 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
}
}
// On Android, iOS and Mac Catalyst, Process.Start() is not supported and
// OS-specific/non-portable APIs must be used to launch the system browser.
#if SUPPORTS_ANDROID
if (OperatingSystem.IsAndroid() && TryLaunchBrowserWithGenericIntent(uri))
{
@ -601,20 +594,26 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
return;
}
#endif
#if SUPPORTS_UIKIT
if ((OperatingSystem.IsIOS() || OperatingSystem.IsMacCatalyst()) && await TryLaunchBrowserWithUIApplicationAsync(uri))
{
context.HandleRequest();
return;
}
#elif SUPPORTS_APPKIT
#endif
#if SUPPORTS_APPKIT
if (OperatingSystem.IsMacOS() && TryLaunchBrowserWithNSWorkspace(uri))
{
context.HandleRequest();
return;
}
#endif
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && await TryLaunchBrowserWithOpenAsync(uri))
{
context.HandleRequest();
return;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && await TryLaunchBrowserWithXdgOpenAsync(uri))
{
context.HandleRequest();
@ -650,8 +649,6 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response is not null, SR.GetResourceString(SR.ID4007));
// This handler only applies to HTTP listener requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpListenerContext()?.Response ??
@ -663,7 +660,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
// Return a message indicating whether the sign-out process
// succeeded or failed and that will be visible by the user.
var buffer = Encoding.UTF8.GetBytes(context.Transaction.Response.Error switch
var buffer = Encoding.UTF8.GetBytes(context.Response.Error switch
{
null or { Length: 0 } => "Logout completed. Please return to the application.",
Errors.AccessDenied => "Logout denied. Please return to the application.",

46
src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs

@ -400,11 +400,10 @@ public static class OpenIddictClientSystemIntegrationHelpers
};
/// <summary>
/// Starts the system browser using ShellExecute.
/// Starts the system browser using the operating system shell.
/// </summary>
/// <param name="uri">The <see cref="Uri"/> to use.</param>
/// <returns><see langword="true"/> if the browser could be started, <see langword="false"/> otherwise.</returns>
[SupportedOSPlatform("linux")]
[SupportedOSPlatform("windows")]
internal static async ValueTask<bool> TryLaunchBrowserWithShellExecuteAsync(Uri uri)
{
@ -501,7 +500,40 @@ public static class OpenIddictClientSystemIntegrationHelpers
#endif
/// <summary>
/// Starts the system browser using xdg-open.
/// Starts the system browser using the "open" executable.
/// </summary>
/// <param name="uri">The <see cref="Uri"/> to use.</param>
/// <returns><see langword="true"/> if the browser could be started, <see langword="false"/> otherwise.</returns>
[SupportedOSPlatform("macos")]
internal static async ValueTask<bool> TryLaunchBrowserWithOpenAsync(Uri uri)
{
try
{
await Task.Run(() => Process.Start(new ProcessStartInfo
{
FileName = "/usr/bin/open",
Arguments = uri.AbsoluteUri,
UseShellExecute = false,
// Note: children processes always inherit the standard input/output/error handles of the
// parent process by default. To ensure the messages logged by the system browser are not
// written to the stdio/stderr of the current process, the streams are always redirected.
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true
}));
return true;
}
catch (Exception exception) when (!OpenIddictHelpers.IsFatal(exception))
{
return false;
}
}
/// <summary>
/// Starts the system browser using the "xdg-open" executable.
/// </summary>
/// <param name="uri">The <see cref="Uri"/> to use.</param>
/// <returns><see langword="true"/> if the browser could be started, <see langword="false"/> otherwise.</returns>
@ -516,9 +548,9 @@ public static class OpenIddictClientSystemIntegrationHelpers
Arguments = uri.AbsoluteUri,
UseShellExecute = false,
// Note: on some Linux distributions, xdg-open is known to propagate errors
// and warnings written to the standard error stream to the parent process.
// To avoid that, the streams are redirected to this instance and ignored.
// Note: children processes always inherit the standard input/output/error handles of the
// parent process by default. To ensure the messages logged by the system browser are not
// written to the stdio/stderr of the current process, the streams are always redirected.
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true
@ -527,7 +559,7 @@ public static class OpenIddictClientSystemIntegrationHelpers
return true;
}
catch (UnauthorizedAccessException)
catch (Exception exception) when (!OpenIddictHelpers.IsFatal(exception))
{
return false;
}

2
src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHttpListener.cs

@ -116,7 +116,7 @@ public sealed class OpenIddictClientSystemIntegrationHttpListener : BackgroundSe
Stack<Exception>? exceptions = null;
for (var port = IPEndPoint.MinPort; port <= IPEndPoint.MaxPort; port++)
for (var port = IPEndPoint.MinPort; port is <= IPEndPoint.MaxPort; port++)
{
cancellationToken.ThrowIfCancellationRequested();

Loading…
Cancel
Save