7 changed files with 197 additions and 184 deletions
@ -0,0 +1,95 @@ |
|||
/* |
|||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|||
* See https://github.com/openiddict/openiddict-core for more information concerning
|
|||
* the license and the contributors participating to this project. |
|||
*/ |
|||
|
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Runtime.CompilerServices; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Options; |
|||
|
|||
namespace OpenIddict.Client.Windows; |
|||
|
|||
/// <summary>
|
|||
/// Contains the logic necessary to handle initial URI protocol activations.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Note: redirected URI protocol activations are handled by <see cref="OpenIddictClientWindowsListener"/>.
|
|||
/// </remarks>
|
|||
[EditorBrowsable(EditorBrowsableState.Never)] |
|||
public sealed class OpenIddictClientWindowsHandler : IHostedService |
|||
{ |
|||
private readonly IOptionsMonitor<OpenIddictClientWindowsOptions> _options; |
|||
private readonly OpenIddictClientWindowsService _service; |
|||
|
|||
/// <summary>
|
|||
/// Creates a new instance of the <see cref="OpenIddictClientWindowsHandler"/> class.
|
|||
/// </summary>
|
|||
/// <param name="options">The OpenIddict client Windows integration options.</param>
|
|||
/// <param name="service">The OpenIddict client Windows service.</param>
|
|||
public OpenIddictClientWindowsHandler( |
|||
IOptionsMonitor<OpenIddictClientWindowsOptions> options, |
|||
OpenIddictClientWindowsService service) |
|||
{ |
|||
_options = options ?? throw new ArgumentNullException(nameof(options)); |
|||
_service = service ?? throw new ArgumentNullException(nameof(service)); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public Task StartAsync(CancellationToken cancellationToken) |
|||
{ |
|||
// Note: initial URI protocol activation handling is implemented as a regular IHostedService
|
|||
// rather than as a BackgroundService to allow blocking the initialization of the host until
|
|||
// the activation is fully processed by the OpenIddict pipeline. By doing that, the UI thread
|
|||
// is not started until redirection requests (like authorization responses) are fully processed,
|
|||
// which allows handling these requests transparently and helps avoid the "flashing window effect":
|
|||
// once a request has been handled by the OpenIddict pipeline, a dedicated handler is responsible
|
|||
// for stopping the application gracefully using the IHostApplicationLifetime.StopApplication() API.
|
|||
|
|||
if (cancellationToken.IsCancellationRequested) |
|||
{ |
|||
return Task.FromCanceled(cancellationToken); |
|||
} |
|||
|
|||
// If the default activation processing logic was disabled in the options, ignore the activation.
|
|||
if (_options.CurrentValue.DisableProtocolActivationProcessing) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
// Determine whether the current instance is initialized to react to a protocol activation.
|
|||
// If it's not, return immediately to avoid adding latency to the application startup process.
|
|||
if (GetProtocolActivation() is not OpenIddictClientWindowsActivation activation) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
return _service.HandleProtocolActivationAsync(activation, cancellationToken); |
|||
|
|||
[MethodImpl(MethodImplOptions.NoInlining)] |
|||
static OpenIddictClientWindowsActivation? GetProtocolActivation() |
|||
{ |
|||
#if SUPPORTS_WINDOWS_RUNTIME
|
|||
// On platforms that support WinRT, always favor the AppInstance.GetActivatedEventArgs() API.
|
|||
if (OpenIddictClientWindowsHelpers.IsWindowsRuntimeSupported() && |
|||
OpenIddictClientWindowsHelpers.GetProtocolActivationUriWithWindowsRuntime() is Uri uri) |
|||
{ |
|||
return new OpenIddictClientWindowsActivation(uri); |
|||
} |
|||
#endif
|
|||
// Otherwise, try to extract the protocol activation from the command line arguments.
|
|||
if (OpenIddictClientWindowsHelpers.GetProtocolActivationUriFromCommandLineArguments( |
|||
Environment.GetCommandLineArgs()) is Uri value) |
|||
{ |
|||
return new OpenIddictClientWindowsActivation(value); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; |
|||
} |
|||
Loading…
Reference in new issue