/// <summary> /// Called when receiving an authorization code. An application may use this context /// to deserialize the code using a custom format and to skip the default logic using /// <see cref="BaseContext{OpenIdConnectServerOptions}.HandleResponse"/>. /// </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 ReceiveAuthorizationCode(ReceiveAuthorizationCodeContext context) => OnReceiveAuthorizationCode(context);
private async Task <AuthenticationTicket> ReceiveAuthorizationCodeAsync(string code, OpenIdConnectMessage request) { try { var notification = new ReceiveAuthorizationCodeContext(Context, Options, request, code) { DataFormat = Options.AuthorizationCodeFormat }; // Sets the default deserializer used to resolve the // authentication ticket corresponding to the authorization code. notification.Deserializer = payload => { return(Task.FromResult(notification.DataFormat?.Unprotect(payload))); }; await Options.Provider.ReceiveAuthorizationCode(notification); // Directly return the authentication ticket if one // has been provided by ReceiveAuthorizationCode. // Treat a non-null ticket like an implicit HandleResponse call. if (notification.HandledResponse || notification.AuthenticationTicket != null) { if (notification.AuthenticationTicket == null) { return(null); } // Ensure the received ticket is an authorization code. if (!notification.AuthenticationTicket.IsAuthorizationCode()) { Logger.LogVerbose("The received token was not an authorization code: {0}.", code); return(null); } return(notification.AuthenticationTicket); } else if (notification.Skipped) { return(null); } var buffer = await Options.Cache.GetAsync(code); if (buffer == null) { return(null); } using (var stream = new MemoryStream(buffer)) using (var reader = new StreamReader(stream)) { // Because authorization codes are guaranteed to be unique, make sure // to remove the current code from the global store before using it. await Options.Cache.RemoveAsync(code); var ticket = await notification.DeserializeTicketAsync(await reader.ReadToEndAsync()); if (ticket == null) { return(null); } // Ensure the received ticket is an authorization code. if (!ticket.IsAuthorizationCode()) { Logger.LogVerbose("The received token was not an authorization code: {0}.", code); return(null); } return(ticket); } } catch (Exception exception) { Logger.LogWarning("An exception occured when deserializing an authorization code.", exception); return(null); } }