Critical Developers

Programmers Knowledge Base

Globally Encrypt Decrypt Query string in ASP.Net core using Middleware

Like HttpModule in ASP.Net Webform we have Middleware in ASP.Net Core.

So lets create a custom middleware which will encrypt/ decrypt querystring globally.

With this approach, Just take care of TempData because we are redirecting a request twice here so would recommend if you are using tempdata use its Keep Method to preserve it on your RazorPage. Lets start-

Step-1: Create a custom middleware

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyDemos.CustomMiddlewares
{
    // Ref-https://docs.microsoft.com/en-us/aspnet/core/migration/http-modules?view=aspnetcore-3.1
    public class EncryptDecryptQueryStringsMiddleware
    {
        private const string PARAMETER_NAME = "_enc";
        private const string ENCRYPTION_KEY = "key";
        private static ASCIIEncoding encoding;
        private static IHttpContextAccessor _httpContextAccessor;
        private readonly IDataProtector _protector;
        private readonly RequestDelegate _next;
        public EncryptDecryptQueryStringsMiddleware(IHttpContextAccessor httpContextAccessor, IDataProtectionProvider provider, RequestDelegate next)
        {
            encoding = new ASCIIEncoding();
            _httpContextAccessor = httpContextAccessor;
            _protector = provider.CreateProtector
("YOURSECRETKEY");
            _next = next;
        }
        public async Task Invoke(HttpContext context)
        {
            if (UriHelper.GetEncodedUrl(context.Request).Contains("?"))
            {
                string contextQuery = GetAbsoluteUri().Query.ToString();
                //
                if (contextQuery.Contains(PARAMETER_NAME))
                {
                    var enc = context.Request.Query[PARAMETER_NAME];
                    enc = _protector.Unprotect(enc);
                    QueryString queryString = new QueryString(enc);
                    context.Request.QueryString = queryString;
                }
                else if (context.Request.Method == "GET")
                {
                    if (contextQuery != "")
                    {
                        string encryptedQuery = _protector.Protect(contextQuery);
                        string redirectToPagePath = context.Request.Path.Value + "?" + PARAMETER_NAME + "=" + encryptedQuery;
                        context.Response.Redirect(redirectToPagePath);
                    }
                }
            }
            await _next.Invoke(context);
        }
        #region Utils
        private static Uri GetAbsoluteUri()
        {
            var request = _httpContextAccessor.HttpContext.Request;
            UriBuilder uriBuilder = new UriBuilder();
            uriBuilder.Scheme = request.Scheme;
            uriBuilder.Host = request.Host.Host;
            uriBuilder.Path = request.Path.ToString();
            uriBuilder.Query = request.QueryString.ToString();
            return uriBuilder.Uri;
        }

        #endregion
    }
    public static class QueryStringMiddlewareExtensions
    {
        public static IApplicationBuilder UseEncryptDecryptQueryStringsMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<EncryptDecryptQueryStringsMiddleware>();
        }
    }
}

Step-2: Use/Inject middleware in Startup.cs

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                //app.UseStatusCodePagesWithRedirects("/Error/{0}");
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            //
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseEncryptDecryptQueryStringsMiddleware();
            //
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
Thats it !!
Comments are closed