diff --git a/src/Microsoft.AspNetCore.Authentication.WsFederation/Events/RemoteSignoutContext.cs b/src/Microsoft.AspNetCore.Authentication.WsFederation/Events/RemoteSignoutContext.cs
new file mode 100644
index 000000000..8aec24a64
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Authentication.WsFederation/Events/RemoteSignoutContext.cs
@@ -0,0 +1,30 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.IdentityModel.Protocols.WsFederation;
+
+namespace Microsoft.AspNetCore.Authentication.WsFederation
+{
+ ///
+ /// An event context for RemoteSignOut.
+ ///
+ public class RemoteSignOutContext : RemoteAuthenticationContext
+ {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public RemoteSignOutContext(HttpContext context, AuthenticationScheme scheme, WsFederationOptions options, WsFederationMessage message)
+ : base(context, scheme, options, new AuthenticationProperties())
+ => ProtocolMessage = message;
+
+ ///
+ /// The signout message.
+ ///
+ public WsFederationMessage ProtocolMessage { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Authentication.WsFederation/Events/WsFederationEvents.cs b/src/Microsoft.AspNetCore.Authentication.WsFederation/Events/WsFederationEvents.cs
index 3dd1c90e9..55c3936f9 100644
--- a/src/Microsoft.AspNetCore.Authentication.WsFederation/Events/WsFederationEvents.cs
+++ b/src/Microsoft.AspNetCore.Authentication.WsFederation/Events/WsFederationEvents.cs
@@ -26,6 +26,11 @@ public class WsFederationEvents : RemoteAuthenticationEvents
///
public Func OnRedirectToIdentityProvider { get; set; } = context => Task.CompletedTask;
+ ///
+ /// Invoked when a wsignoutcleanup request is received at the RemoteSignOutPath endpoint.
+ ///
+ public Func OnRemoteSignOut { get; set; } = context => Task.CompletedTask;
+
///
/// Invoked with the security token that has been extracted from the protocol message.
///
@@ -51,6 +56,11 @@ public class WsFederationEvents : RemoteAuthenticationEvents
///
public virtual Task RedirectToIdentityProvider(RedirectContext context) => OnRedirectToIdentityProvider(context);
+ ///
+ /// Invoked when a wsignoutcleanup request is received at the RemoteSignOutPath endpoint.
+ ///
+ public virtual Task RemoteSignOut(RemoteSignOutContext context) => OnRemoteSignOut(context);
+
///
/// Invoked with the security token that has been extracted from the protocol message.
///
diff --git a/src/Microsoft.AspNetCore.Authentication.WsFederation/LoggingExtensions.cs b/src/Microsoft.AspNetCore.Authentication.WsFederation/LoggingExtensions.cs
index 0f2f9339d..e28b7e15b 100644
--- a/src/Microsoft.AspNetCore.Authentication.WsFederation/LoggingExtensions.cs
+++ b/src/Microsoft.AspNetCore.Authentication.WsFederation/LoggingExtensions.cs
@@ -11,6 +11,9 @@ internal static class LoggingExtensions
private static Action _signInWithoutToken;
private static Action _exceptionProcessingMessage;
private static Action _malformedRedirectUri;
+ private static Action _remoteSignOutHandledResponse;
+ private static Action _remoteSignOutSkipped;
+ private static Action _remoteSignOut;
static LoggingExtensions()
{
@@ -30,6 +33,18 @@ static LoggingExtensions()
eventId: 4,
logLevel: LogLevel.Warning,
formatString: "The sign-out redirect URI '{0}' is malformed.");
+ _remoteSignOutHandledResponse = LoggerMessage.Define(
+ eventId: 5,
+ logLevel: LogLevel.Debug,
+ formatString: "RemoteSignOutContext.HandledResponse");
+ _remoteSignOutSkipped = LoggerMessage.Define(
+ eventId: 6,
+ logLevel: LogLevel.Debug,
+ formatString: "RemoteSignOutContext.Skipped");
+ _remoteSignOut = LoggerMessage.Define(
+ eventId: 7,
+ logLevel: LogLevel.Information,
+ formatString: "Remote signout request processed.");
}
public static void SignInWithoutWresult(this ILogger logger)
@@ -51,5 +66,20 @@ public static void MalformedRedirectUri(this ILogger logger, string uri)
{
_malformedRedirectUri(logger, uri, null);
}
+
+ public static void RemoteSignOutHandledResponse(this ILogger logger)
+ {
+ _remoteSignOutHandledResponse(logger, null);
+ }
+
+ public static void RemoteSignOutSkipped(this ILogger logger)
+ {
+ _remoteSignOutSkipped(logger, null);
+ }
+
+ public static void RemoteSignOut(this ILogger logger)
+ {
+ _remoteSignOut(logger, null);
+ }
}
}
diff --git a/src/Microsoft.AspNetCore.Authentication.WsFederation/WsFederationHandler.cs b/src/Microsoft.AspNetCore.Authentication.WsFederation/WsFederationHandler.cs
index b9c470908..c5848849a 100644
--- a/src/Microsoft.AspNetCore.Authentication.WsFederation/WsFederationHandler.cs
+++ b/src/Microsoft.AspNetCore.Authentication.WsFederation/WsFederationHandler.cs
@@ -51,6 +51,20 @@ public WsFederationHandler(IOptionsMonitor options, ILogger
/// A new instance of the events instance.
protected override Task