public override async Task ValidateClientLogoutRedirectUri(ValidateClientLogoutRedirectUriContext context) { var database = context.HttpContext.RequestServices.GetRequiredService<ApplicationContext>(); // Note: ValidateClientLogoutRedirectUri is not invoked when post_logout_redirect_uri is null. // When provided, post_logout_redirect_uri must exactly match the address registered by the client application. if (!await database.Applications.AnyAsync(application => application.LogoutRedirectUri == context.PostLogoutRedirectUri)) { context.Rejected(error: "invalid_client", description: "Invalid post_logout_redirect_uri"); return; } context.Validated(); }
/// <summary> /// Called to validate that context.PostLogoutRedirectUri a valid and registered URL. /// This only occurs when processing the logout endpoint. The application MUST implement this call, and it MUST validate /// both of those factors before calling context.Validated. If the context.Validated method is called with a given redirectUri parameter, /// then IsValidated will only become true if the incoming redirect URI matches the given redirect URI. /// If context.Validated is not called the request will not proceed further. /// </summary> /// <param name="context">The context of the event carries information in and results out.</param> /// <returns>Task to enable asynchronous execution</returns> public virtual Task ValidateClientLogoutRedirectUri(ValidateClientLogoutRedirectUriContext context) => OnValidateClientLogoutRedirectUri(context);
private async Task <bool> InvokeLogoutEndpointAsync() { OpenIdConnectMessage request = null; // Note: logout requests must be made via GET but POST requests // are also accepted to allow flowing large logout payloads. // See https://openid.net/specs/openid-connect-session-1_0.html#RPLogout if (string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase)) { request = new OpenIdConnectMessage(Request.Query.ToDictionary()) { RequestType = OpenIdConnectRequestType.LogoutRequest }; } else if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase)) { // See http://openid.net/specs/openid-connect-core-1_0.html#FormSerialization if (string.IsNullOrEmpty(Request.ContentType)) { return(await SendErrorPageAsync(new OpenIdConnectMessage { Error = OpenIdConnectConstants.Errors.InvalidRequest, ErrorDescription = "A malformed logout request has been received: " + "the mandatory 'Content-Type' header was missing from the POST request." })); } // May have media/type; charset=utf-8, allow partial match. if (!Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase)) { return(await SendErrorPageAsync(new OpenIdConnectMessage { Error = OpenIdConnectConstants.Errors.InvalidRequest, ErrorDescription = "A malformed logout request has been received: " + "the 'Content-Type' header contained an unexcepted value. " + "Make sure to use 'application/x-www-form-urlencoded'." })); } var form = await Request.ReadFormAsync(Context.RequestAborted); request = new OpenIdConnectMessage(form.ToDictionary()) { RequestType = OpenIdConnectRequestType.LogoutRequest }; } else { Logger.LogInformation("A malformed request has been received by the logout endpoint."); return(await SendErrorPageAsync(new OpenIdConnectMessage { Error = OpenIdConnectConstants.Errors.InvalidRequest, ErrorDescription = "A malformed logout request has been received: " + "make sure to use either GET or POST." })); } // Store the logout request in the ASP.NET context. Context.SetOpenIdConnectRequest(request); // Note: post_logout_redirect_uri is not a mandatory parameter. // See http://openid.net/specs/openid-connect-session-1_0.html#RPLogout if (!string.IsNullOrEmpty(request.PostLogoutRedirectUri)) { var clientNotification = new ValidateClientLogoutRedirectUriContext(Context, Options, request); await Options.Provider.ValidateClientLogoutRedirectUri(clientNotification); if (clientNotification.IsRejected) { Logger.LogDebug("Unable to validate client information"); return(await SendErrorPageAsync(new OpenIdConnectMessage { Error = clientNotification.Error, ErrorDescription = clientNotification.ErrorDescription, ErrorUri = clientNotification.ErrorUri })); } } var notification = new LogoutEndpointContext(Context, Options, request); await Options.Provider.LogoutEndpoint(notification); if (notification.HandledResponse) { return(true); } return(false); }