Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
158 views
in Technique[技术] by (71.8m points)

c# - How to refuse a response intentionally from Asp.net

I am building an ASP.NET webapi restful service that responds to POSTed webhooks coming in from a third party integration partner. That third party has implemented a signing mechanism I can use to verify that the request comes from them and is not a replay attack. The third-party suggests as a best practice that if the signature is bad or if the timestamp is wrong, that I do not respond. At all. No error, no status, nothing. I realize that I don't know how to do this. My controller action determines that the request is bad, but how do I instruct the framework to NOT respond in this case? To intentionally leave the perceived bad actor hanging?

question from:https://stackoverflow.com/questions/65890230/how-to-refuse-a-response-intentionally-from-asp-net

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Based on the comments to the original question, here is the solution I have decided on for now. Note that it does NOT leave the perceived bad actor hanging, but instead responds with an error that can be set in the config file or defaults to 404 NOT FOUND. As far as I can tell, even with Response.Clear() and Response.End(), webapi will send an empty 200 response. So I can't completely adhere to the suggestion of the third party.

using System.Collections.Generic;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using IntegrationResearch.Extension;

namespace IntegrationResearch.Filters
{
    public class VerificationAttribute : ActionFilterAttribute
    {
        public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            await base.OnActionExecutingAsync(actionContext, cancellationToken);

            IList<string> validationErrors = await actionContext.Request.GetSignedRequestVerificationErrorsAsync();  //The code that does the work of checking signed request

            if ((validationErrors?.Count ?? 0) != 0)
            {
                // TODO SG - definitely need to log the issue either way

                throw new HttpResponseException(HttpContext.Current.IsDebuggingEnabled
                    ? new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(string.Join(", ", validationErrors)) }
                    : new HttpResponseMessage(await GetDelayedVerificationFailureStatusCodeAsync()));
            }
        }

        private static async Task<HttpStatusCode> GetDelayedVerificationFailureStatusCodeAsync()
        {
            await Task.Delay(int.TryParse(ConfigurationManager.AppSettings[VerificationFailureDelayMillisecondsConfigKey], out int delayMilliseconds) ? delayMilliseconds : 1000);

            try
            {
                return (HttpStatusCode) int.Parse(ConfigurationManager.AppSettings[VerificationFailureStatusCodeConfigKey]);
            }
            catch
            {
                return HttpStatusCode.NotFound;
            }
        }

        private const string VerificationFailureStatusCodeConfigKey = "VerificationFailureStatusCode";
        private const string VerificationFailureDelayMillisecondsConfigKey = "VerificationFailureDelayMilliseconds";
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...