/// <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);
Ejemplo n.º 2
0
        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);
            }
        }