Home > OS >  How to use custom middlewear for only post and put action method
How to use custom middlewear for only post and put action method

Time:02-14

I have a custom middleware in .net core project that check and validate input to prevent cross site scripting but I want it to be only run on POST and PUT method of the API for performance betterment. Is there any way to do that in .net core?

here is my middleware

    public class AntiXssMiddleware
{

    private readonly RequestDelegate _next;
    private readonly int _statusCode = (int) HttpStatusCode.BadRequest;

    public AntiXssMiddleware(RequestDelegate next)
    {
        _next = next ?? throw new ArgumentNullException(nameof(next));
    }

    public async Task Invoke(HttpContext context)
    {
        // Check XSS in request content
        var originalBody = context.Request.Body;
        try
        {
            var content = await ReadRequestBody(context);

            if (CrossSiteScriptingValidation.IsDangerousString(content))
            {
                await RespondWithAnError(context).ConfigureAwait(false);
                return;
            }

            await _next(context).ConfigureAwait(false);
        }
        finally
        {
            context.Request.Body = originalBody;
        }
    }

    private static async Task<string> ReadRequestBody(HttpContext context)
    {
        var buffer = new MemoryStream();
        await context.Request.Body.CopyToAsync(buffer);
        context.Request.Body = buffer;
        buffer.Position = 0;

        var encoding = Encoding.UTF8;

        var requestContent = await new StreamReader(buffer, encoding).ReadToEndAsync();
        context.Request.Body.Position = 0;

        return requestContent;
    }

    private async Task RespondWithAnError(HttpContext context)
    {
        context.Response.Clear();
        context.Response.Headers.AddHeaders();
        context.Response.ContentType = "application/json; charset=utf-8";
        context.Response.StatusCode = _statusCode;

        await context.Response.WriteAsync("Error from AntiXssMiddleware! Dangerous Script or Tag detected");
    }

}

startup.cs

 app.UseAntiXssMiddleware();

CodePudding user response:

Just check the http method. If it's not neither PUT nor POST, simply continue to the next middleware.

public async Task Invoke(HttpContext context)
{
    var httpMethod = context.Current.Request.HttpMethod;
    if (httpMethod != "PUT" && httpMethod != "POST") {
        await _next(context).ConfigureAwait(false);
    }  
    ...
}

CodePudding user response:

You can use MapWhen (or UseWhen if you want to branch then rejoin the main pipeline) to add logic to branch the request pipeline based on a predicate that you provide. So, if you only wanted your middleware to run on POST or PUT requests you can do something like:

app.MapWhen(ctx => ctx.Request.Method is "PUT" or "POST", appBuilder =>
{
    appBuilder.UseAntiXssMiddleware();
});

// or

app.UseWhen(ctx => ctx.Request.Method is "PUT" or "POST", appBuilder =>
{
    appBuilder.UseAntiXssMiddleware();
});

This would have the desired result of only calling your middleware when the predicate logic is true

  • Related