Example #1
0
        public override async Task <bool> InvokeAsync()
        {
            // Note: due to internal differences between ASP.NET Core and Katana, the request MUST start being processed
            // in InitializeCoreAsync() to ensure the request context is available from AuthenticateCoreAsync() when
            // active authentication is used, as AuthenticateCoreAsync() is always called before InvokeAsync() in this case.

            var transaction = Context.Get <OpenIddictValidationTransaction>(typeof(OpenIddictValidationTransaction).FullName) ??
                              throw new InvalidOperationException("An unknown error occurred while retrieving the OpenIddict validation context.");

            var context = transaction.GetProperty <ProcessRequestContext>(typeof(ProcessRequestContext).FullName) ??
                          throw new InvalidOperationException("An unknown error occurred while retrieving the OpenIddict validation context.");

            if (context.IsRequestHandled)
            {
                return(true);
            }

            else if (context.IsRequestSkipped)
            {
                return(false);
            }

            else if (context.IsRejected)
            {
                var notification = new ProcessErrorContext(transaction)
                {
                    Response = new OpenIddictResponse
                    {
                        Error            = context.Error ?? Errors.InvalidRequest,
                        ErrorDescription = context.ErrorDescription,
                        ErrorUri         = context.ErrorUri
                    }
                };

                await _dispatcher.DispatchAsync(notification);

                if (notification.IsRequestHandled)
                {
                    return(true);
                }

                else if (notification.IsRequestSkipped)
                {
                    return(false);
                }

                throw new InvalidOperationException(new StringBuilder()
                                                    .Append("The OpenID Connect response was not correctly processed. This may indicate ")
                                                    .Append("that the event handler responsible of processing OpenID Connect responses ")
                                                    .Append("was not registered or was explicitly removed from the handlers list.")
                                                    .ToString());
            }

            return(false);
        }
Example #2
0
        public async Task SignInAsync([NotNull] ClaimsPrincipal user, [CanBeNull] AuthenticationProperties properties)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var transaction = Context.Features.Get <OpenIddictServerAspNetCoreFeature>()?.Transaction ??
                              throw new InvalidOperationException("An unknown error occurred while retrieving the OpenIddict server context.");

            transaction.Properties[typeof(AuthenticationProperties).FullName] = properties ?? new AuthenticationProperties();

            var context = new ProcessSignInContext(transaction)
            {
                Principal = user,
                Response  = new OpenIddictResponse()
            };

            await _dispatcher.DispatchAsync(context);

            if (context.IsRequestHandled || context.IsRequestSkipped)
            {
                return;
            }

            else if (context.IsRejected)
            {
                var notification = new ProcessErrorContext(transaction)
                {
                    Response = new OpenIddictResponse
                    {
                        Error            = context.Error ?? Errors.InvalidRequest,
                        ErrorDescription = context.ErrorDescription,
                        ErrorUri         = context.ErrorUri
                    }
                };

                await _dispatcher.DispatchAsync(notification);

                if (notification.IsRequestHandled || context.IsRequestSkipped)
                {
                    return;
                }

                throw new InvalidOperationException(new StringBuilder()
                                                    .Append("The OpenID Connect response was not correctly processed. This may indicate ")
                                                    .Append("that the event handler responsible of processing OpenID Connect responses ")
                                                    .Append("was not registered or was explicitly removed from the handlers list.")
                                                    .ToString());
            }
        }
Example #3
0
        public async Task <bool> HandleRequestAsync()
        {
            // Note: the transaction may be already attached when replaying an ASP.NET Core request
            // (e.g when using the built-in status code pages middleware with the re-execute mode).
            var transaction = Context.Features.Get <OpenIddictServerAspNetCoreFeature>()?.Transaction;

            if (transaction == null)
            {
                // Create a new transaction and attach the HTTP request to make it available to the ASP.NET Core handlers.
                transaction = await _factory.CreateTransactionAsync();

                transaction.Properties[typeof(HttpRequest).FullName] = new WeakReference <HttpRequest>(Request);

                // Attach the OpenIddict server transaction to the ASP.NET Core features
                // so that it can retrieved while performing sign-in/sign-out operations.
                Context.Features.Set(new OpenIddictServerAspNetCoreFeature {
                    Transaction = transaction
                });
            }

            var context = new ProcessRequestContext(transaction);
            await _dispatcher.DispatchAsync(context);

            if (context.IsRequestHandled)
            {
                return(true);
            }

            else if (context.IsRequestSkipped)
            {
                return(false);
            }

            else if (context.IsRejected)
            {
                var notification = new ProcessErrorContext(transaction)
                {
                    Response = new OpenIddictResponse
                    {
                        Error            = context.Error ?? Errors.InvalidRequest,
                        ErrorDescription = context.ErrorDescription,
                        ErrorUri         = context.ErrorUri
                    }
                };

                await _dispatcher.DispatchAsync(notification);

                if (notification.IsRequestHandled)
                {
                    return(true);
                }

                else if (notification.IsRequestSkipped)
                {
                    return(false);
                }

                throw new InvalidOperationException(new StringBuilder()
                                                    .Append("The OpenID Connect response was not correctly processed. This may indicate ")
                                                    .Append("that the event handler responsible of processing OpenID Connect responses ")
                                                    .Append("was not registered or was explicitly removed from the handlers list.")
                                                    .ToString());
            }

            return(false);
        }
        public override async Task <bool> InvokeAsync()
        {
            // Note: the transaction may be already attached when replaying an OWIN request
            // (e.g when using a status code pages middleware re-invoking the OWIN pipeline).
            var transaction = Context.Get <OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName);

            if (transaction == null)
            {
                // Create a new transaction and attach the OWIN request to make it available to the OWIN handlers.
                transaction = await _provider.CreateTransactionAsync();

                transaction.Properties[typeof(IOwinRequest).FullName] = new WeakReference <IOwinRequest>(Request);

                // Attach the OpenIddict server transaction to the OWIN shared dictionary
                // so that it can retrieved while performing sign-in/sign-out operations.
                Context.Set(typeof(OpenIddictServerTransaction).FullName, transaction);
            }

            var context = new ProcessRequestContext(transaction);
            await _provider.DispatchAsync(context);

            if (context.IsRequestHandled)
            {
                return(true);
            }

            else if (context.IsRequestSkipped)
            {
                return(false);
            }

            else if (context.IsRejected)
            {
                var notification = new ProcessErrorContext(transaction)
                {
                    Response = new OpenIddictResponse
                    {
                        Error            = context.Error ?? Errors.InvalidRequest,
                        ErrorDescription = context.ErrorDescription,
                        ErrorUri         = context.ErrorUri
                    }
                };

                await _provider.DispatchAsync(notification);

                if (notification.IsRequestHandled)
                {
                    return(true);
                }

                else if (notification.IsRequestSkipped)
                {
                    return(false);
                }

                throw new InvalidOperationException(new StringBuilder()
                                                    .Append("The OpenID Connect response was not correctly processed. This may indicate ")
                                                    .Append("that the event handler responsible of processing OpenID Connect responses ")
                                                    .Append("was not registered or was explicitly removed from the handlers list.")
                                                    .ToString());
            }

            return(false);
        }
        protected override async Task TeardownCoreAsync()
        {
            // Note: OWIN authentication handlers cannot reliabily write to the response stream
            // from ApplyResponseGrantAsync or ApplyResponseChallengeAsync because these methods
            // are susceptible to be invoked from AuthenticationHandler.OnSendingHeaderCallback,
            // where calling Write or WriteAsync on the response stream may result in a deadlock
            // on hosts using streamed responses. To work around this limitation, this handler
            // doesn't implement ApplyResponseGrantAsync but TeardownCoreAsync, which is never called
            // by AuthenticationHandler.OnSendingHeaderCallback. In theory, this would prevent
            // OpenIddictServerOwinMiddleware from both applying the response grant and allowing
            // the next middleware in the pipeline to alter the response stream but in practice,
            // OpenIddictServerOwinMiddleware is assumed to be the only middleware allowed to write
            // to the response stream when a response grant (sign-in/out or challenge) was applied.

            var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);

            if (challenge != null)
            {
                var transaction = Context.Get <OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName);
                if (transaction == null)
                {
                    throw new InvalidOperationException("An OpenID Connect response cannot be returned from this endpoint.");
                }

                var context = new ProcessChallengeContext(transaction)
                {
                    Response = new OpenIddictResponse
                    {
                        Error            = GetProperty(challenge.Properties, Properties.Error),
                        ErrorDescription = GetProperty(challenge.Properties, Properties.ErrorDescription),
                        ErrorUri         = GetProperty(challenge.Properties, Properties.ErrorUri)
                    }
                };

                await _provider.DispatchAsync(context);

                if (context.IsRequestHandled || context.IsRequestSkipped)
                {
                    return;
                }

                else if (context.IsRejected)
                {
                    var notification = new ProcessErrorContext(transaction)
                    {
                        Response = new OpenIddictResponse
                        {
                            Error            = context.Error ?? Errors.InvalidRequest,
                            ErrorDescription = context.ErrorDescription,
                            ErrorUri         = context.ErrorUri
                        }
                    };

                    await _provider.DispatchAsync(notification);

                    if (notification.IsRequestHandled || context.IsRequestSkipped)
                    {
                        return;
                    }

                    throw new InvalidOperationException(new StringBuilder()
                                                        .Append("The OpenID Connect response was not correctly processed. This may indicate ")
                                                        .Append("that the event handler responsible of processing OpenID Connect responses ")
                                                        .Append("was not registered or was explicitly removed from the handlers list.")
                                                        .ToString());
                }
Example #6
0
        protected override async Task TeardownCoreAsync()
        {
            // Note: OWIN authentication handlers cannot reliabily write to the response stream
            // from ApplyResponseGrantAsync or ApplyResponseChallengeAsync because these methods
            // are susceptible to be invoked from AuthenticationHandler.OnSendingHeaderCallback,
            // where calling Write or WriteAsync on the response stream may result in a deadlock
            // on hosts using streamed responses. To work around this limitation, this handler
            // doesn't implement ApplyResponseGrantAsync but TeardownCoreAsync, which is never called
            // by AuthenticationHandler.OnSendingHeaderCallback. In theory, this would prevent
            // OpenIddictValidationOwinMiddleware from both applying the response grant and allowing
            // the next middleware in the pipeline to alter the response stream but in practice,
            // OpenIddictValidationOwinMiddleware is assumed to be the only middleware allowed to write
            // to the response stream when a response grant (sign-in/out or challenge) was applied.

            // Note: unlike the ASP.NET Core host, the OWIN host MUST check whether the status code
            // corresponds to a challenge response, as LookupChallenge() will always return a non-null
            // value when active authentication is used, even if no challenge was actually triggered.
            var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);

            if (challenge != null && (Response.StatusCode == 401 || Response.StatusCode == 403))
            {
                var transaction = Context.Get <OpenIddictValidationTransaction>(typeof(OpenIddictValidationTransaction).FullName) ??
                                  throw new InvalidOperationException("An unknown error occurred while retrieving the OpenIddict validation context.");

                transaction.Properties[typeof(AuthenticationProperties).FullName] = challenge.Properties ?? new AuthenticationProperties();

                var context = new ProcessChallengeContext(transaction)
                {
                    Response = new OpenIddictResponse()
                };

                await _dispatcher.DispatchAsync(context);

                if (context.IsRequestHandled || context.IsRequestSkipped)
                {
                    return;
                }

                else if (context.IsRejected)
                {
                    var notification = new ProcessErrorContext(transaction)
                    {
                        Response = new OpenIddictResponse
                        {
                            Error            = context.Error ?? Errors.InvalidRequest,
                            ErrorDescription = context.ErrorDescription,
                            ErrorUri         = context.ErrorUri
                        }
                    };

                    await _dispatcher.DispatchAsync(notification);

                    if (notification.IsRequestHandled || context.IsRequestSkipped)
                    {
                        return;
                    }

                    throw new InvalidOperationException(new StringBuilder()
                                                        .Append("The OpenID Connect response was not correctly processed. This may indicate ")
                                                        .Append("that the event handler responsible of processing OpenID Connect responses ")
                                                        .Append("was not registered or was explicitly removed from the handlers list.")
                                                        .ToString());
                }
            }
        }