Permalink
Browse files

Allow requests to be rejected from the new ProcessChallengeResponse/P…

…rocessSigninResponse/ProcessSignoutResponse events
  • Loading branch information...
PinpointTownes committed Oct 11, 2017
1 parent c561a34 commit 3801427b4a69a927b7ec56156e92b66caba92eee
@@ -5,47 +5,41 @@
*/
using AspNet.Security.OpenIdConnect.Primitives;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
namespace AspNet.Security.OpenIdConnect.Server
{
/// <summary>
/// Represents the context class associated with the
/// <see cref="OpenIdConnectServerProvider.ProcessChallengeResponse"/> event.
/// </summary>
public class ProcessChallengeResponseContext : BaseControlContext
public class ProcessChallengeResponseContext : BaseValidatingContext
{
/// <summary>
/// Creates a new instance of the <see cref="ProcessChallengeResponseContext"/> class.
/// </summary>
public ProcessChallengeResponseContext(
HttpContext context,
OpenIdConnectServerOptions options,
AuthenticationTicket ticket,
AuthenticationProperties properties,
OpenIdConnectRequest request,
OpenIdConnectResponse response)
: base(context)
: base(context, options, request)
{
Options = options;
Ticket = ticket;
Request = request;
Validate();
Properties = properties;
Response = response;
}
/// <summary>
/// Gets the options used by the OpenID Connect server.
/// Gets the OpenID Connect response.
/// </summary>
public OpenIdConnectServerOptions Options { get; }
/// <summary>
/// Gets the authorization or token request.
/// </summary>
public new OpenIdConnectRequest Request { get; }
public new OpenIdConnectResponse Response { get; }
/// <summary>
/// Gets the authorization or token response.
/// Gets or sets the authentication properties.
/// </summary>
public new OpenIdConnectResponse Response { get; }
public AuthenticationProperties Properties { get; set; }
}
}
@@ -14,7 +14,7 @@ namespace AspNet.Security.OpenIdConnect.Server
/// Represents the context class associated with the
/// <see cref="OpenIdConnectServerProvider.ProcessSigninResponse"/> event.
/// </summary>
public class ProcessSigninResponseContext : BaseControlContext
public class ProcessSigninResponseContext : BaseValidatingTicketContext
{
/// <summary>
/// Creates a new instance of the <see cref="ProcessSigninResponseContext"/> class.
@@ -25,26 +25,14 @@ public class ProcessSigninResponseContext : BaseControlContext
AuthenticationTicket ticket,
OpenIdConnectRequest request,
OpenIdConnectResponse response)
: base(context)
: base(context, options, request, ticket)
{
Options = options;
Ticket = ticket;
Request = request;
Validate();
Response = response;
}
/// <summary>
/// Gets the options used by the OpenID Connect server.
/// </summary>
public OpenIdConnectServerOptions Options { get; }
/// <summary>
/// Gets the authorization or token request.
/// </summary>
public new OpenIdConnectRequest Request { get; }
/// <summary>
/// Gets the authorization or token response.
/// Gets the OpenID Connect response.
/// </summary>
public new OpenIdConnectResponse Response { get; }
@@ -5,47 +5,41 @@
*/
using AspNet.Security.OpenIdConnect.Primitives;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Authentication;
namespace AspNet.Security.OpenIdConnect.Server
{
/// <summary>
/// Represents the context class associated with the
/// <see cref="OpenIdConnectServerProvider.ProcessSignoutResponse"/> event.
/// </summary>
public class ProcessSignoutResponseContext : BaseControlContext
public class ProcessSignoutResponseContext : BaseValidatingContext
{
/// <summary>
/// Creates a new instance of the <see cref="ProcessSignoutResponseContext"/> class.
/// </summary>
public ProcessSignoutResponseContext(
HttpContext context,
OpenIdConnectServerOptions options,
AuthenticationTicket ticket,
AuthenticationProperties properties,
OpenIdConnectRequest request,
OpenIdConnectResponse response)
: base(context)
: base(context, options, request)
{
Options = options;
Ticket = ticket;
Request = request;
Validate();
Properties = properties;
Response = response;
}
/// <summary>
/// Gets the options used by the OpenID Connect server.
/// Gets the OpenID Connect response.
/// </summary>
public OpenIdConnectServerOptions Options { get; }
/// <summary>
/// Gets the logout request.
/// </summary>
public new OpenIdConnectRequest Request { get; }
public new OpenIdConnectResponse Response { get; }
/// <summary>
/// Gets the logout response.
/// Gets or sets the authentication properties.
/// </summary>
public new OpenIdConnectResponse Response { get; }
public AuthenticationProperties Properties { get; set; }
}
}
@@ -374,6 +374,30 @@ private async Task<bool> HandleSignInAsync(AuthenticationTicket ticket)
return false;
}
else if (notification.IsRejected)
{
Logger.LogError("The request was rejected with the following error: {Error} ; {Description}",
/* Error: */ notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
/* Description: */ notification.ErrorDescription);
if (request.IsAuthorizationRequest())
{
return await SendAuthorizationResponseAsync(new OpenIdConnectResponse
{
Error = notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
ErrorDescription = notification.ErrorDescription,
ErrorUri = notification.ErrorUri
});
}
return await SendTokenResponseAsync(new OpenIdConnectResponse
{
Error = notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
ErrorDescription = notification.ErrorDescription,
ErrorUri = notification.ErrorUri
});
}
// Flow the changes made to the ticket.
ticket = notification.Ticket;
@@ -497,18 +521,9 @@ private async Task<bool> HandleSignInAsync(AuthenticationTicket ticket)
}
protected override Task HandleSignOutAsync(SignOutContext context)
{
// Create a new ticket containing an empty identity and
// the authentication properties extracted from the context.
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(new ClaimsIdentity()),
new AuthenticationProperties(context.Properties),
context.AuthenticationScheme);
return HandleSignOutAsync(ticket);
}
=> HandleSignOutAsync(new AuthenticationProperties(context.Properties));
private async Task<bool> HandleSignOutAsync(AuthenticationTicket ticket)
private async Task<bool> HandleSignOutAsync(AuthenticationProperties properties)
{
// Extract the OpenID Connect request from the ASP.NET Core context.
// If it cannot be found or doesn't correspond to a logout request,
@@ -526,12 +541,12 @@ private async Task<bool> HandleSignOutAsync(AuthenticationTicket ticket)
throw new InvalidOperationException("A response has already been sent.");
}
Logger.LogTrace("A log-out operation was triggered: {Properties}.", ticket.Properties.Items);
Logger.LogTrace("A log-out operation was triggered: {Properties}.", properties.Items);
// Prepare a new OpenID Connect response.
response = new OpenIdConnectResponse();
var notification = new ProcessSignoutResponseContext(Context, Options, ticket, request, response);
var notification = new ProcessSignoutResponseContext(Context, Options, properties, request, response);
await Options.Provider.ProcessSignoutResponse(notification);
if (notification.HandledResponse)
@@ -548,25 +563,30 @@ private async Task<bool> HandleSignOutAsync(AuthenticationTicket ticket)
return false;
}
else if (notification.IsRejected)
{
Logger.LogError("The request was rejected with the following error: {Error} ; {Description}",
/* Error: */ notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
/* Description: */ notification.ErrorDescription);
return await SendLogoutResponseAsync(new OpenIdConnectResponse
{
Error = notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
ErrorDescription = notification.ErrorDescription,
ErrorUri = notification.ErrorUri
});
}
return await SendLogoutResponseAsync(response);
}
protected override Task<bool> HandleForbiddenAsync(ChallengeContext context)
=> HandleUnauthorizedAsync(context);
protected override Task<bool> HandleUnauthorizedAsync(ChallengeContext context)
{
// Create a new ticket containing an empty identity and
// the authentication properties extracted from the context.
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(new ClaimsIdentity()),
new AuthenticationProperties(context.Properties),
context.AuthenticationScheme);
=> HandleUnauthorizedAsync(new AuthenticationProperties(context.Properties));
return HandleUnauthorizedAsync(ticket);
}
private async Task<bool> HandleUnauthorizedAsync(AuthenticationTicket ticket)
private async Task<bool> HandleUnauthorizedAsync(AuthenticationProperties properties)
{
// Extract the OpenID Connect request from the ASP.NET Core context.
// If it cannot be found or doesn't correspond to an authorization
@@ -587,15 +607,15 @@ private async Task<bool> HandleUnauthorizedAsync(AuthenticationTicket ticket)
// Prepare a new OpenID Connect response.
response = new OpenIdConnectResponse
{
Error = ticket.GetProperty(OpenIdConnectConstants.Properties.Error),
ErrorDescription = ticket.GetProperty(OpenIdConnectConstants.Properties.ErrorDescription),
ErrorUri = ticket.GetProperty(OpenIdConnectConstants.Properties.ErrorUri)
Error = properties.GetProperty(OpenIdConnectConstants.Properties.Error),
ErrorDescription = properties.GetProperty(OpenIdConnectConstants.Properties.ErrorDescription),
ErrorUri = properties.GetProperty(OpenIdConnectConstants.Properties.ErrorUri)
};
// Remove the error/error_description/error_uri properties from the ticket.
ticket.RemoveProperty(OpenIdConnectConstants.Properties.Error)
.RemoveProperty(OpenIdConnectConstants.Properties.ErrorDescription)
.RemoveProperty(OpenIdConnectConstants.Properties.ErrorUri);
properties.RemoveProperty(OpenIdConnectConstants.Properties.Error)
.RemoveProperty(OpenIdConnectConstants.Properties.ErrorDescription)
.RemoveProperty(OpenIdConnectConstants.Properties.ErrorUri);
if (string.IsNullOrEmpty(response.Error))
{
@@ -611,9 +631,9 @@ private async Task<bool> HandleUnauthorizedAsync(AuthenticationTicket ticket)
"The token request was rejected by the authorization server.";
}
Logger.LogTrace("A challenge operation was triggered: {Properties}.", ticket.Properties.Items);
Logger.LogTrace("A challenge operation was triggered: {Properties}.", properties.Items);
var notification = new ProcessChallengeResponseContext(Context, Options, ticket, request, response);
var notification = new ProcessChallengeResponseContext(Context, Options, properties, request, response);
await Options.Provider.ProcessChallengeResponse(notification);
if (notification.HandledResponse)
@@ -630,6 +650,39 @@ private async Task<bool> HandleUnauthorizedAsync(AuthenticationTicket ticket)
return false;
}
else if (notification.IsRejected)
{
Logger.LogError("The request was rejected with the following error: {Error} ; {Description}",
/* Error: */ notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
/* Description: */ notification.ErrorDescription);
if (request.IsAuthorizationRequest())
{
return await SendAuthorizationResponseAsync(new OpenIdConnectResponse
{
Error = notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
ErrorDescription = notification.ErrorDescription,
ErrorUri = notification.ErrorUri
});
}
return await SendTokenResponseAsync(new OpenIdConnectResponse
{
Error = notification.Error ?? OpenIdConnectConstants.Errors.InvalidRequest,
ErrorDescription = notification.ErrorDescription,
ErrorUri = notification.ErrorUri
});
}
// Flow the changes made to the properties.
properties = notification.Properties;
// Create a new ticket containing an empty identity and
// the authentication properties extracted from the context.
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(new ClaimsIdentity()),
properties, Options.AuthenticationScheme);
if (request.IsAuthorizationRequest())
{
return await SendAuthorizationResponseAsync(response, ticket);
@@ -7,45 +7,39 @@
using AspNet.Security.OpenIdConnect.Primitives;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Notifications;
namespace Owin.Security.OpenIdConnect.Server
{
/// <summary>
/// Represents the context class associated with the
/// <see cref="OpenIdConnectServerProvider.ProcessChallengeResponse"/> event.
/// </summary>
public class ProcessChallengeResponseContext : BaseNotification<OpenIdConnectServerOptions>
public class ProcessChallengeResponseContext : BaseValidatingContext
{
/// <summary>
/// Creates a new instance of the <see cref="ProcessChallengeResponseContext"/> class.
/// </summary>
public ProcessChallengeResponseContext(
IOwinContext context,
OpenIdConnectServerOptions options,
AuthenticationTicket ticket,
AuthenticationProperties properties,
OpenIdConnectRequest request,
OpenIdConnectResponse response)
: base(context, options)
: base(context, options, request)
{
Ticket = ticket;
Request = request;
Validate();
Properties = properties;
Response = response;
}
/// <summary>
/// Gets the authorization or token request.
/// </summary>
public new OpenIdConnectRequest Request { get; }
/// <summary>
/// Gets the authorization or token response.
/// Gets the OpenID Connect response.
/// </summary>
public new OpenIdConnectResponse Response { get; }
/// <summary>
/// Gets the authentication ticket.
/// Gets or sets the authentication properties.
/// </summary>
public AuthenticationTicket Ticket { get; }
public AuthenticationProperties Properties { get; set; }
}
}
Oops, something went wrong.

0 comments on commit 3801427

Please sign in to comment.