diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs b/src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs
index fda22c03..37e7904c 100644
--- a/src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs
+++ b/src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs
@@ -76,6 +76,13 @@ namespace OpenIddict.Server
RedirectUri = address;
}
+
+ ///
+ /// Gets or sets the security principal extracted from the id_token_hint, if available.
+ /// Note: the principal may not represent the user currently logged in,
+ /// so additional validation is strongly encouraged when using this property.
+ ///
+ public ClaimsPrincipal IdentityTokenHintPrincipal { get; set; }
}
///
@@ -91,6 +98,13 @@ namespace OpenIddict.Server
: base(transaction)
{
}
+
+ ///
+ /// Gets or sets the security principal extracted from the id_token_hint, if available.
+ /// Note: the principal may not represent the user currently logged in,
+ /// so additional validation is strongly encouraged when using this property.
+ ///
+ public ClaimsPrincipal IdentityTokenHintPrincipal { get; set; }
}
///
diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.Session.cs b/src/OpenIddict.Server/OpenIddictServerEvents.Session.cs
index 2682256b..bcb96db8 100644
--- a/src/OpenIddict.Server/OpenIddictServerEvents.Session.cs
+++ b/src/OpenIddict.Server/OpenIddictServerEvents.Session.cs
@@ -5,6 +5,7 @@
*/
using System;
+using System.Security.Claims;
using JetBrains.Annotations;
namespace OpenIddict.Server
@@ -68,6 +69,13 @@ namespace OpenIddict.Server
PostLogoutRedirectUri = address;
}
+
+ ///
+ /// Gets or sets the security principal extracted from the id_token_hint, if available.
+ /// Note: the principal may not represent the user currently logged in,
+ /// so additional validation is strongly encouraged when using this property.
+ ///
+ public ClaimsPrincipal IdentityTokenHintPrincipal { get; set; }
}
///
@@ -85,14 +93,11 @@ namespace OpenIddict.Server
}
///
- /// Gets a boolean indicating whether the logout request should be processed.
- ///
- public bool IsLogoutAllowed { get; private set; }
-
- ///
- /// Allow the logout request to be processed.
+ /// Gets or sets the security principal extracted from the id_token_hint, if available.
+ /// Note: the principal may not represent the user currently logged in,
+ /// so additional validation is strongly encouraged when using this property.
///
- public void ProcessLogout() => IsLogoutAllowed = true;
+ public ClaimsPrincipal IdentityTokenHintPrincipal { get; set; }
}
///
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
index 76705003..b8178226 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Immutable;
+using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -55,6 +56,11 @@ namespace OpenIddict.Server
ValidateGrantTypePermissions.Descriptor,
ValidateScopePermissions.Descriptor,
+ /*
+ * Authorization request handling:
+ */
+ AttachIdentityTokenHintPrincipal.Descriptor,
+
/*
* Authorization response processing:
*/
@@ -1027,7 +1033,9 @@ namespace OpenIddict.Server
// Note: the expiration date associated with an identity token used as an id_token_hint is deliberately ignored.
- // Store the security principal extracted from the identity token as an environment property.
+ // Attach the security principal extracted from the identity token to the
+ // validation context and store it as an environment property.
+ context.IdentityTokenHintPrincipal = notification.Principal;
context.Transaction.Properties[Properties.AmbientPrincipal] = notification.Principal;
}
}
@@ -1541,6 +1549,43 @@ namespace OpenIddict.Server
}
}
+ ///
+ /// Contains the logic responsible of attaching the principal extracted from the id_token_hint to the event context.
+ ///
+ public class AttachIdentityTokenHintPrincipal : IOpenIddictServerHandler
+ {
+ ///
+ /// Gets the default descriptor definition assigned to this handler.
+ ///
+ public static OpenIddictServerHandlerDescriptor Descriptor { get; }
+ = OpenIddictServerHandlerDescriptor.CreateBuilder()
+ .UseSingletonHandler()
+ .SetOrder(int.MinValue + 100_000)
+ .Build();
+
+ ///
+ /// Processes the event.
+ ///
+ /// The context associated with the event to process.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public ValueTask HandleAsync([NotNull] HandleAuthorizationRequestContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ if (context.Transaction.Properties.TryGetValue(Properties.AmbientPrincipal, out var principal))
+ {
+ context.IdentityTokenHintPrincipal ??= (ClaimsPrincipal) principal;
+ }
+
+ return default;
+ }
+ }
+
///
/// Contains the logic responsible of inferring the redirect URL
/// used to send the response back to the client application.
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
index 9ece230a..f74f3f54 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Immutable;
+using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -40,6 +41,11 @@ namespace OpenIddict.Server
ValidateIdTokenHint.Descriptor,
ValidateClientPostLogoutRedirectUri.Descriptor,
+ /*
+ * Logout request handling:
+ */
+ AttachIdentityTokenHintPrincipal.Descriptor,
+
/*
* Logout response processing:
*/
@@ -255,26 +261,23 @@ namespace OpenIddict.Server
return;
}
- if (notification.IsLogoutAllowed)
+ var @event = new ProcessSignoutContext(context.Transaction)
{
- var @event = new ProcessSignoutContext(context.Transaction)
- {
- Response = new OpenIddictResponse()
- };
+ Response = new OpenIddictResponse()
+ };
- await _provider.DispatchAsync(@event);
+ await _provider.DispatchAsync(@event);
- if (@event.IsRequestHandled)
- {
- context.HandleRequest();
- return;
- }
+ if (@event.IsRequestHandled)
+ {
+ context.HandleRequest();
+ return;
+ }
- else if (@event.IsRequestSkipped)
- {
- context.SkipRequest();
- return;
- }
+ else if (@event.IsRequestSkipped)
+ {
+ context.SkipRequest();
+ return;
}
throw new InvalidOperationException(new StringBuilder()
@@ -459,7 +462,9 @@ namespace OpenIddict.Server
// Note: the expiration date associated with an identity token used as an id_token_hint is deliberately ignored.
- // Store the security principal extracted from the identity token as an environment property.
+ // Attach the security principal extracted from the identity token to the
+ // validation context and store it as an environment property.
+ context.IdentityTokenHintPrincipal = notification.Principal;
context.Transaction.Properties[Properties.AmbientPrincipal] = notification.Principal;
}
}
@@ -549,6 +554,43 @@ namespace OpenIddict.Server
}
}
+ ///
+ /// Contains the logic responsible of attaching the principal extracted from the id_token_hint to the event context.
+ ///
+ public class AttachIdentityTokenHintPrincipal : IOpenIddictServerHandler
+ {
+ ///
+ /// Gets the default descriptor definition assigned to this handler.
+ ///
+ public static OpenIddictServerHandlerDescriptor Descriptor { get; }
+ = OpenIddictServerHandlerDescriptor.CreateBuilder()
+ .UseSingletonHandler()
+ .SetOrder(int.MinValue + 100_000)
+ .Build();
+
+ ///
+ /// Processes the event.
+ ///
+ /// The context associated with the event to process.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public ValueTask HandleAsync([NotNull] HandleLogoutRequestContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ if (context.Transaction.Properties.TryGetValue(Properties.AmbientPrincipal, out var principal))
+ {
+ context.IdentityTokenHintPrincipal ??= (ClaimsPrincipal) principal;
+ }
+
+ return default;
+ }
+ }
+
///
/// Contains the logic responsible of inferring the redirect URL
/// used to send the response back to the client application.