Пример #1
0
        /// <summary>
        ///   Performs the actions needed to add an authentication challenge to the inner IHttpActionResult, if needed.
        /// </summary>
        ///
        /// <param name="context">The authentication challenge context to consider.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        ///
        /// <returns>A Task that will perform the authentication challenge.</returns>
        ///
        /// <remarks>
        ///   This method will be executed by the framework after the action has executed, regardless of whether or not a challenge
        ///   should be generated.  Before generating the challenge, determine if it
        /// </remarks>
        ///
        public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.Request;

            // If there was an authenticated principal associated with the request or there was a result generated that should not
            // overridden, then no challenge is needed.

            if ((cancellationToken.IsCancellationRequested) || (request.GetRequestContext()?.Principal != null) || (!OrderFulfillmentAuthenticateAttributeAttribute.ShouldOverrideResponse(context)))
            {
                return;
            }

            var result = OrderFulfillmentAuthenticateAttributeAttribute.ProcessRequest(request, cancellationToken, true);

            // If there was no available handler located after processing the request, then attempt to retrieve the
            // default challenge handler.

            if (result == null)
            {
                var handler = OrderFulfillmentAuthenticateAttributeAttribute.SelectDefaultChallengeHandler(request.GetDependencyScope());

                if (handler != null)
                {
                    result = new ProcessResult(OrderFulfillmentAuthenticateAttributeAttribute.EmptyStringDictionary, handler);
                }
            }

            // If there was no available challenge handler, authentication is not possible.  Make
            // no alterations to the current response.

            if ((cancellationToken.IsCancellationRequested) || (result == null))
            {
                return;
            }

            // If the handler was able to produce a challenge, then clear any existing result/response and
            // set the new Unauthorized with the correct challenge.

            var challenge = result.AuthenticationHandler.GenerateChallenge(result.AuthenticationTokens, context);

            if (challenge != null)
            {
                context.ActionContext.Response?.Dispose();
                context.ActionContext.Response = null;

                context.Result = new UnauthorizedResult(new[] { challenge }, request);

                try
                {
                    var locator = request.GetDependencyScope();
                    var logger  = (locator.GetService(typeof(ILogger)) as ILogger);

                    if (logger != null)
                    {
                        var body = await request.SafeReadContentAsStringAsync();

                        logger.WithCorrelationId(request?.GetOrderFulfillmentCorrelationId())
                        .Information($"Response: {{Response}} { Environment.NewLine } Authentication is needed; a challenge was issued for {{Route}} with Headers: [{{Headers}}]",
                                     HttpStatusCode.Unauthorized,
                                     request?.RequestUri,
                                     request?.Headers);
                    }
                }

                catch
                {
                    // Do nothing; logging is a non-critical operation that should not cause
                    // cascading failures.
                }
            }
        }