Browse Source

Update the logout endpoint logic to not trigger a sign-out response by default and reword some of the exception messages

pull/1009/head
Kévin Chalet 6 years ago
parent
commit
e0909c87a8
  1. 6
      src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs
  2. 6
      src/OpenIddict.Server/OpenIddictServerEvents.Exchange.cs
  3. 12
      src/OpenIddict.Server/OpenIddictServerEvents.Session.cs
  4. 10
      src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
  5. 33
      src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
  6. 10
      src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
  7. 55
      src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
  8. 16
      test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs
  9. 64
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Session.cs
  10. 16
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
  11. 16
      test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs

6
src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs

@ -91,6 +91,12 @@ namespace OpenIddict.Server
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary>
/// <param name="principal">The claims principal.</param>
public void SignIn(ClaimsPrincipal principal) => Principal = principal;
} }
/// <summary> /// <summary>

6
src/OpenIddict.Server/OpenIddictServerEvents.Exchange.cs

@ -60,6 +60,12 @@ namespace OpenIddict.Server
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary>
/// <param name="principal">The claims principal.</param>
public void SignIn(ClaimsPrincipal principal) => Principal = principal;
} }
/// <summary> /// <summary>

12
src/OpenIddict.Server/OpenIddictServerEvents.Session.cs

@ -5,7 +5,6 @@
*/ */
using System; using System;
using System.Security.Claims;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace OpenIddict.Server namespace OpenIddict.Server
@ -86,11 +85,14 @@ namespace OpenIddict.Server
} }
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the id_token_hint, if available. /// Gets a boolean indicating whether a sign-out should be triggered.
/// Note: the principal may not represent the user currently logged in,
/// so additional validation is strongly encouraged when using this property.
/// </summary> /// </summary>
public ClaimsPrincipal IdentityTokenHintPrincipal { get; set; } public bool IsSignOutTriggered { get; private set; }
/// <summary>
/// Allows OpenIddict to return a sign-out response.
/// </summary>
public void SignOut() => IsSignOutTriggered = true;
} }
/// <summary> /// <summary>

10
src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs

@ -300,10 +300,12 @@ namespace OpenIddict.Server
} }
throw new InvalidOperationException(new StringBuilder() throw new InvalidOperationException(new StringBuilder()
.Append("The authorization request was not handled. To handle authorization requests, ") .Append("The authorization request was not handled. To handle authorization requests in a controller, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleAuthorizationRequestContext>' ") .Append("create a custom controller action with the same route as the authorization endpoint ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.") .Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.") .AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableAuthorizationEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleAuthorizationRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString()); .ToString());
} }
} }

33
src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs

@ -256,21 +256,21 @@ namespace OpenIddict.Server
return; return;
} }
var @event = new ProcessSignInContext(context.Transaction) if (notification.Principal == null)
{
Principal = notification.Principal,
Response = new OpenIddictResponse()
};
if (@event.Principal == null)
{ {
// Note: no authentication type is deliberately specified to represent an unauthenticated identity. // Note: no authentication type is deliberately specified to represent an unauthenticated identity.
var principal = new ClaimsPrincipal(new ClaimsIdentity()); var principal = new ClaimsPrincipal(new ClaimsIdentity());
principal.SetScopes(context.Request.GetScopes()); principal.SetScopes(context.Request.GetScopes());
@event.Principal = principal; notification.Principal = principal;
} }
var @event = new ProcessSignInContext(context.Transaction)
{
Principal = notification.Principal,
Response = new OpenIddictResponse()
};
await _dispatcher.DispatchAsync(@event); await _dispatcher.DispatchAsync(@event);
if (@event.IsRequestHandled) if (@event.IsRequestHandled)
@ -293,13 +293,6 @@ namespace OpenIddict.Server
uri: @event.ErrorUri); uri: @event.ErrorUri);
return; return;
} }
throw new InvalidOperationException(new StringBuilder()
.Append("The device request was not handled. To handle device requests, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleDeviceRequestContext>' ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.")
.ToString());
} }
} }
@ -1066,10 +1059,12 @@ namespace OpenIddict.Server
} }
throw new InvalidOperationException(new StringBuilder() throw new InvalidOperationException(new StringBuilder()
.Append("The verification request was not handled. To handle verification requests, ") .Append("The verification request was not handled. To handle verification requests in a controller, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleVerificationRequestContext>' ") .Append("create a custom controller action with the same route as the verification endpoint ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.") .Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.") .AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableVerificationEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleVerificationRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString()); .ToString());
} }
} }

10
src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs

@ -300,10 +300,12 @@ namespace OpenIddict.Server
} }
throw new InvalidOperationException(new StringBuilder() throw new InvalidOperationException(new StringBuilder()
.Append("The token request was not handled. To handle token requests, ") .Append("The token request was not handled. To handle token requests in a controller, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleTokenRequestContext>' ") .Append("create a custom controller action with the same route as the token endpoint ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.") .Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.") .AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableTokenEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleTokenRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString()); .ToString());
} }
} }

55
src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs

@ -242,39 +242,44 @@ namespace OpenIddict.Server
return; return;
} }
var @event = new ProcessSignOutContext(context.Transaction) if (notification.IsSignOutTriggered)
{ {
Response = new OpenIddictResponse() var @event = new ProcessSignOutContext(context.Transaction)
}; {
Response = new OpenIddictResponse()
};
await _dispatcher.DispatchAsync(@event); await _dispatcher.DispatchAsync(@event);
if (@event.IsRequestHandled) if (@event.IsRequestHandled)
{ {
context.HandleRequest(); context.HandleRequest();
return; return;
} }
else if (@event.IsRequestSkipped) else if (@event.IsRequestSkipped)
{ {
context.SkipRequest(); context.SkipRequest();
return; return;
} }
else if (@event.IsRejected) else if (@event.IsRejected)
{ {
context.Reject( context.Reject(
error: @event.Error ?? Errors.InvalidRequest, error: @event.Error ?? Errors.InvalidRequest,
description: @event.ErrorDescription, description: @event.ErrorDescription,
uri: @event.ErrorUri); uri: @event.ErrorUri);
return; return;
}
} }
throw new InvalidOperationException(new StringBuilder() throw new InvalidOperationException(new StringBuilder()
.Append("The logout request was not handled. To handle logout requests, ") .Append("The logout request was not handled. To handle logout requests in a controller, ")
.Append("create a class implementing 'IOpenIddictServerHandler<HandleLogoutRequestContext>' ") .Append("create a custom controller action with the same route as the logout endpoint ")
.AppendLine("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.") .Append("and enable the pass-through mode in the server ASP.NET Core or OWIN options using ")
.Append("Alternatively, enable the pass-through mode to handle them at a later stage.") .AppendLine("'services.AddOpenIddict().AddServer().UseAspNetCore().EnableLogoutEndpointPassthrough()'.")
.Append("Alternatively, create a class implementing 'IOpenIddictServerHandler<HandleLogoutRequestContext>' ")
.Append("and register it using 'services.AddOpenIddict().AddServer().AddEventHandler()'.")
.ToString()); .ToString());
} }
} }

16
test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs

@ -188,6 +188,14 @@ namespace OpenIddict.Server.AspNetCore.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder => options.AddEventHandler<ProcessRequestContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
@ -221,6 +229,14 @@ namespace OpenIddict.Server.AspNetCore.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder => options.AddEventHandler<ProcessRequestContext>(builder =>
{ {
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>

64
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Session.cs

@ -261,6 +261,14 @@ namespace OpenIddict.Server.FunctionalTests
options.SetLogoutEndpointUris("/signout"); options.SetLogoutEndpointUris("/signout");
options.Configure(options => options.IgnoreEndpointPermissions = false); options.Configure(options => options.IgnoreEndpointPermissions = false);
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
}); });
await using var client = await server.CreateClientAsync(); await using var client = await server.CreateClientAsync();
@ -473,6 +481,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder => options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
@ -504,6 +520,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder => options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
@ -539,6 +563,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder => options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
@ -568,6 +600,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder => options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
@ -594,6 +634,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.SetLogoutEndpointUris("/signout"); options.SetLogoutEndpointUris("/signout");
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
}); });
await using var client = await server.CreateClientAsync(); await using var client = await server.CreateClientAsync();
@ -616,6 +664,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.SetLogoutEndpointUris("/signout"); options.SetLogoutEndpointUris("/signout");
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
}); });
await using var client = await server.CreateClientAsync(); await using var client = await server.CreateClientAsync();
@ -640,6 +696,14 @@ namespace OpenIddict.Server.FunctionalTests
options.EnableDegradedMode(); options.EnableDegradedMode();
options.SetLogoutEndpointUris("/signout"); options.SetLogoutEndpointUris("/signout");
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ApplyLogoutResponseContext>(builder => options.AddEventHandler<ApplyLogoutResponseContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {

16
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs

@ -4147,6 +4147,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessSignOutContext>(builder => options.AddEventHandler<ProcessSignOutContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
@ -4175,6 +4183,14 @@ namespace OpenIddict.Server.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessSignOutContext>(builder => options.AddEventHandler<ProcessSignOutContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {

16
test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs

@ -144,6 +144,14 @@ namespace OpenIddict.Server.Owin.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder => options.AddEventHandler<ProcessRequestContext>(builder =>
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
@ -177,6 +185,14 @@ namespace OpenIddict.Server.Owin.FunctionalTests
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.AddEventHandler<HandleLogoutRequestContext>(builder =>
builder.UseInlineHandler(context =>
{
context.SignOut();
return default;
}));
options.AddEventHandler<ProcessRequestContext>(builder => options.AddEventHandler<ProcessRequestContext>(builder =>
{ {
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>

Loading…
Cancel
Save