diff --git a/Directory.Build.targets b/Directory.Build.targets index a3a9128c..03ab2b05 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -86,6 +86,7 @@ $(DefineConstants);SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION_POLICY $(DefineConstants);SUPPORTS_MULTIPLE_VALUES_IN_QUERYHELPERS $(DefineConstants);SUPPORTS_ONE_SHOT_HASHING_METHODS + $(DefineConstants);SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON $(DefineConstants);SUPPORTS_PEM_ENCODED_KEY_IMPORT $(DefineConstants);SUPPORTS_WINFORMS_TASK_DIALOG $(DefineConstants);SUPPORTS_NAMED_PIPE_STATIC_FACTORY_WITH_ACL @@ -104,6 +105,18 @@ $(DefineConstants);SUPPORTS_AUTHENTICATION_HANDLER_SELECTION_FALLBACK + + $(DefineConstants);SUPPORTS_WINDOWS_RUNTIME + + - - - - - - - + + + + + + + - + - - - - - - - + + + + + + + - + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - + + + + + + - + - - - - - - + + + + + + - + - - - - - - + + + + + + - - - - - - - - - + + + + + + + + + - + - - - - - - + + + + + + - - - - + + + + - + - - - - - - + + + + + + - + diff --git a/sandbox/OpenIddict.Sandbox.Console.Client/Worker.cs b/sandbox/OpenIddict.Sandbox.Console.Client/Worker.cs index bda068a0..982dffae 100644 --- a/sandbox/OpenIddict.Sandbox.Console.Client/Worker.cs +++ b/sandbox/OpenIddict.Sandbox.Console.Client/Worker.cs @@ -22,7 +22,10 @@ public class Worker : IHostedService RegistryKey? root = null; // Create the registry entries necessary to handle URI protocol activations. - // Note: the application MUST be run once as an administrator for this to work. + // Note: the application MUST be run once as an administrator for this to work, + // so this should typically be done by a dedicated installer or a setup script. + // Alternatively, the application can be packaged and use windows.protocol to + // register the protocol handler/custom URI scheme with the operation system. try { root = Registry.ClassesRoot.OpenSubKey("openiddict-sandbox-console-client"); diff --git a/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj b/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj index b45ed69c..802e1f8f 100644 --- a/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj +++ b/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj @@ -2,7 +2,7 @@ WinExe - net48;net7.0-windows + net48;net7.0-windows7.0 true true true diff --git a/sandbox/OpenIddict.Sandbox.WinForms.Client/Worker.cs b/sandbox/OpenIddict.Sandbox.WinForms.Client/Worker.cs index 1649f280..d9fb4999 100644 --- a/sandbox/OpenIddict.Sandbox.WinForms.Client/Worker.cs +++ b/sandbox/OpenIddict.Sandbox.WinForms.Client/Worker.cs @@ -23,7 +23,10 @@ public class Worker : IHostedService RegistryKey? root = null; // Create the registry entries necessary to handle URI protocol activations. - // Note: the application MUST be run once as an administrator for this to work. + // Note: the application MUST be run once as an administrator for this to work, + // so this should typically be done by a dedicated installer or a setup script. + // Alternatively, the application can be packaged and use windows.protocol to + // register the protocol handler/custom URI scheme with the operation system. try { root = Registry.ClassesRoot.OpenSubKey("openiddict-sandbox-winforms-client"); diff --git a/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj b/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj index f52b25ae..81dcf221 100644 --- a/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj +++ b/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj @@ -2,7 +2,7 @@ WinExe - net48;net7.0-windows + net48;net7.0-windows10.0.17763 true true true diff --git a/sandbox/OpenIddict.Sandbox.Wpf.Client/Worker.cs b/sandbox/OpenIddict.Sandbox.Wpf.Client/Worker.cs index 03132a09..d6723830 100644 --- a/sandbox/OpenIddict.Sandbox.Wpf.Client/Worker.cs +++ b/sandbox/OpenIddict.Sandbox.Wpf.Client/Worker.cs @@ -23,7 +23,10 @@ public class Worker : IHostedService RegistryKey? root = null; // Create the registry entries necessary to handle URI protocol activations. - // Note: the application MUST be run once as an administrator for this to work. + // Note: the application MUST be run once as an administrator for this to work, + // so this should typically be done by a dedicated installer or a setup script. + // Alternatively, the application can be packaged and use windows.protocol to + // register the protocol handler/custom URI scheme with the operation system. try { root = Registry.ClassesRoot.OpenSubKey("openiddict-sandbox-wpf-client"); diff --git a/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj b/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj index 85d938b9..ec269502 100644 --- a/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj +++ b/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj @@ -1,7 +1,13 @@  - net461;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + true diff --git a/src/OpenIddict.Abstractions/OpenIddictResources.resx b/src/OpenIddict.Abstractions/OpenIddictResources.resx index 839c114e..c0ac3dfa 100644 --- a/src/OpenIddict.Abstractions/OpenIddictResources.resx +++ b/src/OpenIddict.Abstractions/OpenIddictResources.resx @@ -1453,6 +1453,12 @@ To apply post-logout redirection responses, create a class implementing 'IOpenId An explicit client URI must be set when using the OpenIddict client Windows integration. To set the client URI, use 'services.AddOpenIddict().AddClient().SetClientUri()'. + + The default system browser couldn't be started. If the application executes inside a sandbox, make sure it is allowed to launch URIs or spawn new processes. + + + A pipe name must be manually set in the OpenIddict Windows integration options when no application name was configured in the .NET generic host options. To set the pipe name, call 'services.AddOpenIddict().AddClient().UseWindows().SetPipeName()'. + The security token is missing. diff --git a/src/OpenIddict.Client.DataProtection/OpenIddict.Client.DataProtection.csproj b/src/OpenIddict.Client.DataProtection/OpenIddict.Client.DataProtection.csproj index b7cf1a36..19da7821 100644 --- a/src/OpenIddict.Client.DataProtection/OpenIddict.Client.DataProtection.csproj +++ b/src/OpenIddict.Client.DataProtection/OpenIddict.Client.DataProtection.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj b/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj index cde3e6f6..69e6a030 100644 --- a/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj +++ b/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddict.Client.WebIntegration.csproj b/src/OpenIddict.Client.WebIntegration/OpenIddict.Client.WebIntegration.csproj index 46c16841..d028e5a5 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddict.Client.WebIntegration.csproj +++ b/src/OpenIddict.Client.WebIntegration/OpenIddict.Client.WebIntegration.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Client.Windows/OpenIddict.Client.Windows.csproj b/src/OpenIddict.Client.Windows/OpenIddict.Client.Windows.csproj index a537af61..868626e5 100644 --- a/src/OpenIddict.Client.Windows/OpenIddict.Client.Windows.csproj +++ b/src/OpenIddict.Client.Windows/OpenIddict.Client.Windows.csproj @@ -1,8 +1,18 @@  - net461;netcoreapp3.1;net6.0-windows;net7.0-windows + + net461; + netcoreapp3.1; + net6.0-windows7.0; + net6.0-windows10.0.17763; + net7.0-windows7.0; + net7.0-windows10.0.17763; + netstandard2.0 + + true true + true @@ -19,10 +29,18 @@ + Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '5.0'))) Or + ('$(TargetFrameworkIdentifier)' == '.NETStandard') "> + + + + diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsActivation.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsActivation.cs index bfa354b6..22d2031c 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsActivation.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsActivation.cs @@ -16,10 +16,10 @@ namespace OpenIddict.Client.Windows; public sealed class OpenIddictClientWindowsActivation { /// - /// Gets or sets the command line arguments used to + /// Gets or sets the activation arguments used to /// launch the current instance of the application. /// - public ImmutableArray CommandLineArguments { get; set; } + public ImmutableArray ActivationArguments { get; set; } /// /// Gets or sets a boolean indicating whether the activation diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsConfiguration.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsConfiguration.cs index cd96a1ae..c4c11dbf 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsConfiguration.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsConfiguration.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.IO.Pipes; +using System.Runtime.CompilerServices; using System.Security.AccessControl; using System.Security.Principal; using System.Text; @@ -86,6 +87,11 @@ public sealed class OpenIddictClientWindowsConfiguration : IConfigureOptions OpenIddictClientWindowsHelpers.IsWindowsRuntimeSupported() && + OpenIddictClientWindowsHelpers.HasAppContainerToken(identity); +#else + => false; +#endif } } diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.Authentication.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.Authentication.cs index e98a6308..9e539524 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.Authentication.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.Authentication.cs @@ -54,28 +54,54 @@ public static partial class OpenIddictClientWindowsHandlers .Build(); /// - public ValueTask HandleAsync(ApplyAuthorizationRequestContext context) + public async ValueTask HandleAsync(ApplyAuthorizationRequestContext context) { if (context is null) { throw new ArgumentNullException(nameof(context)); } + // Note: the OpenIddict Windows integration is designed to work as a universal Windows package. + // As such, multiple types of application models must be supported to cover most scenarios. E.g: + // + // - Classical Win32 applications, for which no application-specific restriction is enforced. + // - Win32 applications running in an AppContainer, that are very similar to UWP applications. + // - Classical UWP applications, for which strict application restrictions are enforced. + // - Full-trust UWP applications, that are rare but very similar to classical Win32 applications. + // - Modern/hybrid Windows applications, that can be sandboxed or run as full-trust applications. + // + // Since .NET Standard 2.0 support for UWP was only introduced in Windows 10 1709 (also known + // as Fall Creators Update) and OpenIddict requires Windows 10 1809 as the minimum supported + // version, Windows 8/8.1's Metro-style/universal applications are deliberately not supported. + Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008)); var uri = OpenIddictHelpers.AddQueryStringParameters( - new Uri(context.AuthorizationEndpoint, UriKind.Absolute), - context.Transaction.Request.GetParameters().ToDictionary( + uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute), + parameters: context.Transaction.Request.GetParameters().ToDictionary( parameter => parameter.Key, parameter => new StringValues((string?[]?) parameter.Value))); - Process.Start(new ProcessStartInfo +#if SUPPORTS_WINDOWS_RUNTIME + // While Process.Start()/ShellExecuteEx() can typically be used without any particular restriction + // by non-sandboxed desktop applications to launch the default system browser, calling these + // APIs in sandboxed applications will result in an UnauthorizedAccessException being thrown. + // + // To avoid that, the OpenIddict host needs to determine whether the platform supports Windows + // Runtime APIs and favor the Launcher.LaunchUriAsync() API when it's offered by the platform. + + if (OpenIddictClientWindowsHelpers.IsWindowsRuntimeSupported() && await + OpenIddictClientWindowsHelpers.TryLaunchBrowserWithWindowsRuntimeAsync(uri)) { - FileName = uri.AbsoluteUri, - UseShellExecute = true - }); + return; + } +#endif + if (await OpenIddictClientWindowsHelpers.TryLaunchBrowserWithShellExecuteAsync(uri)) + { + return; + } - return default; + throw new InvalidOperationException(SR.GetResourceString(SR.ID0385)); } } } diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.cs index 5fb126f5..b77b13db 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHandlers.cs @@ -99,11 +99,11 @@ public static partial class OpenIddictClientWindowsHandlers // // For more information, see https://devblogs.microsoft.com/oldnewthing/20060515-07/?p=31203. - { CommandLineArguments: [_, string argument] } when Uri.TryCreate(argument, UriKind.Absolute, out Uri? uri) && + { ActivationArguments: [_, string argument] } when Uri.TryCreate(argument, UriKind.Absolute, out Uri? uri) && !uri.IsFile && uri.IsWellFormedOriginalString() => (new Uri(uri.GetLeftPart(UriPartial.Authority), UriKind.Absolute), uri), - { CommandLineArguments: [string argument] } when Uri.TryCreate(argument, UriKind.Absolute, out Uri? uri) && + { ActivationArguments: [string argument] } when Uri.TryCreate(argument, UriKind.Absolute, out Uri? uri) && !uri.IsFile && uri.IsWellFormedOriginalString() => (new Uri(uri.GetLeftPart(UriPartial.Authority), UriKind.Absolute), uri), @@ -458,23 +458,25 @@ public static partial class OpenIddictClientWindowsHandlers impersonationLevel: TokenImpersonationLevel.None, inheritability : HandleInheritability.None)) { + // Wait for the target to accept the pipe connection. + await stream.ConnectAsync(source.Token); + // Write the type of message stored in the shared memory and the // version used to identify the binary serialization format. writer.Write(0x01); writer.Write(0x01); // Write the number of arguments present in the activation. - writer.Write(activation.CommandLineArguments.Length); + writer.Write(activation.ActivationArguments.Length); // Write all the arguments present in the activation. - for (var index = 0; index < activation.CommandLineArguments.Length; index++) + for (var index = 0; index < activation.ActivationArguments.Length; index++) { - writer.Write(activation.CommandLineArguments[index]); + writer.Write(activation.ActivationArguments[index]); } - // Wait for the process to accept the pipe connection, and transfer the binary content. + // Transfer the payload to the target. buffer.Seek(0L, SeekOrigin.Begin); - await stream.ConnectAsync(source.Token); await buffer.CopyToAsync(stream, bufferSize: 81_920, source.Token); } diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHelpers.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHelpers.cs index 9e1e1414..0fec0045 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHelpers.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsHelpers.cs @@ -4,6 +4,20 @@ * the license and the contributors participating to this project. */ +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using System.Security.Principal; + +#if SUPPORTS_WINDOWS_RUNTIME +using Windows.ApplicationModel.Activation; +using Windows.ApplicationModel; +using Windows.Foundation.Metadata; +using Windows.System; +#endif + namespace OpenIddict.Client.Windows; /// @@ -18,4 +32,169 @@ public static class OpenIddictClientWindowsHelpers /// The instance or if it couldn't be found. public static OpenIddictClientWindowsActivation? GetWindowsActivation(this OpenIddictClientTransaction transaction) => transaction.GetProperty(typeof(OpenIddictClientWindowsActivation).FullName!); + +#if SUPPORTS_WINDOWS_RUNTIME + /// + /// Determines whether the Windows Runtime APIs are supported on this platform. + /// + /// if the Windows Runtime APIs are supported, otherwise. + [MethodImpl(MethodImplOptions.AggressiveInlining), SupportedOSPlatformGuard("windows10.0.17763")] + internal static bool IsWindowsRuntimeSupported() + { + // Note: as WinRT is only supported on Windows 8 and higher, trying to call any of the + // WinRT APIs on previous versions of Windows will typically result in type-load or + // type-initialization exceptions. To prevent that, this method acts as a platform + // guard that will prevent the WinRT projections from being loaded by the runtime on + // platforms that don't support it. Since OpenIddict declares Windows 10 1809 as the + // oldest supported version in the package, it is also used for the runtime check. + +#if SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON + return OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17763); +#else + if (Environment.OSVersion.Platform is PlatformID.Win32NT && + Environment.OSVersion.Version >= new Version(10, 0, 17763)) + { + return true; + } + + // Note: on older versions of .NET, Environment.OSVersion.Version is known to be affected by + // the compatibility shims used by Windows 10+ when the application doesn't have a manifest + // that explicitly indicates it's compatible with Windows 10 and higher. To avoid that, a + // second pass using RuntimeInformation.OSDescription (that calls NtDll.RtlGetVersion() under + // the hood) is made. Note: no version is returned on UWP due to the missing Win32 API. + return RuntimeInformation.OSDescription.StartsWith("Microsoft Windows ", StringComparison.OrdinalIgnoreCase) && + RuntimeInformation.OSDescription["Microsoft Windows ".Length..] is string value && + Version.TryParse(value, out Version? version) && version >= new Version(10, 0, 17763); +#endif + } + + /// + /// Determines whether the specified identity contains an AppContainer + /// token, indicating it's running in an AppContainer sandbox. + /// + /// The . + /// + /// if the specified identity contains an + /// AppContainer token, otherwise. + /// + [SupportedOSPlatformGuard("windows10.0.17763")] + internal static unsafe bool HasAppContainerToken(WindowsIdentity identity) + { + if (identity is null) + { + throw new ArgumentNullException(nameof(identity)); + } + + int* buffer = stackalloc int[1]; + + if (!GetTokenInformation( + TokenHandle : identity.Token, + TokenInformationClass : /* TokenIsAppContainer */ 29, + TokenInformation : new IntPtr(buffer), + TokenInformationLength: sizeof(int), + ReturnLength : out _)) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + return *buffer is not 0; + + [DllImport("advapi32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool GetTokenInformation( + IntPtr TokenHandle, + uint TokenInformationClass, + IntPtr TokenInformation, + uint TokenInformationLength, + out uint ReturnLength); + } + + /// + /// Resolves the protocol activation using the Windows Runtime APIs, if applicable. + /// + /// + /// The if the application instance was activated + /// via a protocol activation, otherwise. + /// + [MethodImpl(MethodImplOptions.NoInlining), SupportedOSPlatform("windows10.0.17763")] + internal static Uri? GetProtocolActivationUriWithWindowsRuntime() + { + if (!ApiInformation.IsMethodPresent(typeof(AppInstance).FullName, + nameof(AppInstance.GetActivatedEventArgs), inputParameterCount: 0)) + { + return null; + } + + try + { + return AppInstance.GetActivatedEventArgs() is + ProtocolActivatedEventArgs args ? args.Uri : null; + } + + catch + { + return null; + } + } + + /// + /// Starts the system browser using the Windows Runtime APIs. + /// + /// The to use. + /// if the browser could be started, otherwise. + [MethodImpl(MethodImplOptions.NoInlining), SupportedOSPlatform("windows10.0.17763")] + internal static async Task TryLaunchBrowserWithWindowsRuntimeAsync(Uri uri) + { + // Note: with the materialization of Project Centennial/Desktop Bridge in Windows 10 1607 + // (also known as Anniversary Update), desktop applications that don't have a package + // identity are now allowed to use most of the WinRT APIs. Since OpenIddict's UWP support + // is implemented via a .NET Standard 2.0 TFM (which requires Windows 10 1809), it is assumed + // at this point that Launcher.LaunchUriAsync() can be used in both types of applications. + + if (!ApiInformation.IsMethodPresent(typeof(Launcher).FullName, + nameof(Launcher.LaunchUriAsync), inputParameterCount: 1)) + { + return false; + } + + try + { + return await Launcher.LaunchUriAsync(uri); + } + + catch (UnauthorizedAccessException) + { + return false; + } + } +#endif + + /// + /// Starts the system browser using ShellExecute. + /// + /// The to use. + /// if the browser could be started, otherwise. + internal static async Task TryLaunchBrowserWithShellExecuteAsync(Uri uri) + { + try + { + await Task.Run(() => Process.Start(new ProcessStartInfo + { + FileName = uri.AbsoluteUri, + UseShellExecute = true + })); + + return true; + } + + catch (UnauthorizedAccessException) + { + return false; + } + + catch (Win32Exception exception) when (exception.NativeErrorCode is 5) + { + return false; + } + } } diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsListener.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsListener.cs index 97eba740..80c9ac97 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsListener.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsListener.cs @@ -66,11 +66,12 @@ public sealed class OpenIddictClientWindowsListener : BackgroundService outBufferSize : 0, pipeSecurity : _options.CurrentValue.PipeSecurity, inheritability : HandleInheritability.None, - additionalAccessRights : 0); + additionalAccessRights : default); - // Wait for a writer to connect to the named pipe, - // copy its content to the memory stream and rewind it. + // Wait for a writer to connect to the named pipe. await stream.WaitForConnectionAsync(stoppingToken); + + // Copy the content to the memory stream asynchronously and rewind it. await stream.CopyToAsync(buffer, bufferSize: 81_920, stoppingToken); buffer.Seek(0L, SeekOrigin.Begin); @@ -110,7 +111,7 @@ public sealed class OpenIddictClientWindowsListener : BackgroundService transaction.SetProperty(typeof(OpenIddictClientWindowsActivation).FullName!, new OpenIddictClientWindowsActivation { - CommandLineArguments = builder.MoveToImmutable(), + ActivationArguments = builder.MoveToImmutable(), IsActivationRedirected = true }); diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsOptions.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsOptions.cs index 351b31ff..6fb653cf 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsOptions.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsOptions.cs @@ -44,7 +44,8 @@ public sealed class OpenIddictClientWindowsOptions /// to enable inter-process communication and handle protocol activation redirections. /// /// - /// If no value is explicitly set, a default policy is automatically created. + /// If no value is explicitly set, a default policy is automatically created + /// (unless the application is running inside an AppContainer sandbox). /// public PipeSecurity PipeSecurity { get; set; } = default!; } diff --git a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsService.cs b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsService.cs index 5158b26b..9666ae33 100644 --- a/src/OpenIddict.Client.Windows/OpenIddictClientWindowsService.cs +++ b/src/OpenIddict.Client.Windows/OpenIddictClientWindowsService.cs @@ -9,10 +9,6 @@ using System.ComponentModel; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -#if !SUPPORTS_HOST_APPLICATION_LIFETIME -using IHostApplicationLifetime = Microsoft.Extensions.Hosting.IApplicationLifetime; -#endif - namespace OpenIddict.Client.Windows; /// @@ -60,7 +56,7 @@ public sealed class OpenIddictClientWindowsService : IHostedService transaction.SetProperty(typeof(OpenIddictClientWindowsActivation).FullName!, new OpenIddictClientWindowsActivation { - CommandLineArguments = ImmutableArray.CreateRange(Environment.GetCommandLineArgs()), + ActivationArguments = GetActivationArguments(), IsActivationRedirected = false }); @@ -96,6 +92,19 @@ public sealed class OpenIddictClientWindowsService : IHostedService scope.Dispose(); } } + + static ImmutableArray GetActivationArguments() + { +#if SUPPORTS_WINDOWS_RUNTIME + if (OpenIddictClientWindowsHelpers.IsWindowsRuntimeSupported() && + OpenIddictClientWindowsHelpers.GetProtocolActivationUriWithWindowsRuntime() is Uri uri) + { + return ImmutableArray.Create(uri.AbsoluteUri); + } +#endif + + return ImmutableArray.CreateRange(Environment.GetCommandLineArgs()); + } } /// diff --git a/src/OpenIddict.Client/OpenIddict.Client.csproj b/src/OpenIddict.Client/OpenIddict.Client.csproj index 7129b0da..e6f3f3c5 100644 --- a/src/OpenIddict.Client/OpenIddict.Client.csproj +++ b/src/OpenIddict.Client/OpenIddict.Client.csproj @@ -1,7 +1,16 @@  - net461;net472;net48;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Core/OpenIddict.Core.csproj b/src/OpenIddict.Core/OpenIddict.Core.csproj index 74c47405..0ca1ae64 100644 --- a/src/OpenIddict.Core/OpenIddict.Core.csproj +++ b/src/OpenIddict.Core/OpenIddict.Core.csproj @@ -1,7 +1,15 @@  - net461;net472;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + net472; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj b/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj index ec1c96c0..57322353 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.MongoDb/OpenIddict.MongoDb.csproj b/src/OpenIddict.MongoDb/OpenIddict.MongoDb.csproj index fdd34cf3..b55c8c63 100644 --- a/src/OpenIddict.MongoDb/OpenIddict.MongoDb.csproj +++ b/src/OpenIddict.MongoDb/OpenIddict.MongoDb.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + false false diff --git a/src/OpenIddict.Quartz/OpenIddict.Quartz.csproj b/src/OpenIddict.Quartz/OpenIddict.Quartz.csproj index e363b65c..08477ab6 100644 --- a/src/OpenIddict.Quartz/OpenIddict.Quartz.csproj +++ b/src/OpenIddict.Quartz/OpenIddict.Quartz.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Server.DataProtection/OpenIddict.Server.DataProtection.csproj b/src/OpenIddict.Server.DataProtection/OpenIddict.Server.DataProtection.csproj index 38e3e2af..96c94c93 100644 --- a/src/OpenIddict.Server.DataProtection/OpenIddict.Server.DataProtection.csproj +++ b/src/OpenIddict.Server.DataProtection/OpenIddict.Server.DataProtection.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Server/OpenIddict.Server.csproj b/src/OpenIddict.Server/OpenIddict.Server.csproj index 7f0979ac..c9d68989 100644 --- a/src/OpenIddict.Server/OpenIddict.Server.csproj +++ b/src/OpenIddict.Server/OpenIddict.Server.csproj @@ -1,7 +1,16 @@  - net461;net472;net48;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Validation.DataProtection/OpenIddict.Validation.DataProtection.csproj b/src/OpenIddict.Validation.DataProtection/OpenIddict.Validation.DataProtection.csproj index 644d81ab..9dc42aae 100644 --- a/src/OpenIddict.Validation.DataProtection/OpenIddict.Validation.DataProtection.csproj +++ b/src/OpenIddict.Validation.DataProtection/OpenIddict.Validation.DataProtection.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj b/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj index 12a80420..95a8810d 100644 --- a/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj +++ b/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict.Validation/OpenIddict.Validation.csproj b/src/OpenIddict.Validation/OpenIddict.Validation.csproj index 855e4f4e..c6232298 100644 --- a/src/OpenIddict.Validation/OpenIddict.Validation.csproj +++ b/src/OpenIddict.Validation/OpenIddict.Validation.csproj @@ -1,7 +1,15 @@  - net461;net472;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + net472; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + diff --git a/src/OpenIddict/OpenIddict.csproj b/src/OpenIddict/OpenIddict.csproj index 9a48fab7..18062f9c 100644 --- a/src/OpenIddict/OpenIddict.csproj +++ b/src/OpenIddict/OpenIddict.csproj @@ -1,7 +1,14 @@  - net461;netcoreapp3.1;net6.0;net7.0;netstandard2.0;netstandard2.1 + + net461; + netcoreapp3.1; + net6.0; + net7.0; + netstandard2.0; + netstandard2.1 + false false diff --git a/test/OpenIddict.Client.AspNetCore.IntegrationTests/OpenIddict.Client.AspNetCore.IntegrationTests.csproj b/test/OpenIddict.Client.AspNetCore.IntegrationTests/OpenIddict.Client.AspNetCore.IntegrationTests.csproj index 21be6a8c..f292689c 100644 --- a/test/OpenIddict.Client.AspNetCore.IntegrationTests/OpenIddict.Client.AspNetCore.IntegrationTests.csproj +++ b/test/OpenIddict.Client.AspNetCore.IntegrationTests/OpenIddict.Client.AspNetCore.IntegrationTests.csproj @@ -1,7 +1,14 @@ - net461;net472;net48;netcoreapp3.1;net6.0;net7.0 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0 + diff --git a/test/OpenIddict.Client.IntegrationTests/OpenIddict.Client.IntegrationTests.csproj b/test/OpenIddict.Client.IntegrationTests/OpenIddict.Client.IntegrationTests.csproj index ee1c2a7e..c385f238 100644 --- a/test/OpenIddict.Client.IntegrationTests/OpenIddict.Client.IntegrationTests.csproj +++ b/test/OpenIddict.Client.IntegrationTests/OpenIddict.Client.IntegrationTests.csproj @@ -1,7 +1,14 @@  - net461;net472;net48;netcoreapp3.1;net6.0;net7.0 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0 + diff --git a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddict.Server.AspNetCore.IntegrationTests.csproj b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddict.Server.AspNetCore.IntegrationTests.csproj index f1ff247f..fefe017c 100644 --- a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddict.Server.AspNetCore.IntegrationTests.csproj +++ b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddict.Server.AspNetCore.IntegrationTests.csproj @@ -1,7 +1,14 @@  - net461;net472;net48;netcoreapp3.1;net6.0;net7.0 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0 + diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddict.Server.IntegrationTests.csproj b/test/OpenIddict.Server.IntegrationTests/OpenIddict.Server.IntegrationTests.csproj index 2a2e919a..345dbc60 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddict.Server.IntegrationTests.csproj +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddict.Server.IntegrationTests.csproj @@ -1,7 +1,14 @@  - net461;net472;net48;netcoreapp3.1;net6.0;net7.0 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0 + diff --git a/test/OpenIddict.Server.Tests/OpenIddict.Server.Tests.csproj b/test/OpenIddict.Server.Tests/OpenIddict.Server.Tests.csproj index 871142d5..71c1a5b5 100644 --- a/test/OpenIddict.Server.Tests/OpenIddict.Server.Tests.csproj +++ b/test/OpenIddict.Server.Tests/OpenIddict.Server.Tests.csproj @@ -1,7 +1,13 @@  - net461;net472;netcoreapp3.1;net6.0;net7.0 + + net461; + net472; + netcoreapp3.1; + net6.0; + net7.0 + diff --git a/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddict.Validation.AspNetCore.IntegrationTests.csproj b/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddict.Validation.AspNetCore.IntegrationTests.csproj index 22cc4e94..eebb2a9e 100644 --- a/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddict.Validation.AspNetCore.IntegrationTests.csproj +++ b/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddict.Validation.AspNetCore.IntegrationTests.csproj @@ -1,7 +1,14 @@ - net461;net472;net48;netcoreapp3.1;net6.0;net7.0 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0 + diff --git a/test/OpenIddict.Validation.IntegrationTests/OpenIddict.Validation.IntegrationTests.csproj b/test/OpenIddict.Validation.IntegrationTests/OpenIddict.Validation.IntegrationTests.csproj index c2df8eed..db732663 100644 --- a/test/OpenIddict.Validation.IntegrationTests/OpenIddict.Validation.IntegrationTests.csproj +++ b/test/OpenIddict.Validation.IntegrationTests/OpenIddict.Validation.IntegrationTests.csproj @@ -1,7 +1,14 @@  - net461;net472;net48;netcoreapp3.1;net6.0;net7.0 + + net461; + net472; + net48; + netcoreapp3.1; + net6.0; + net7.0 +