中间件加密查询字符串

时间:2016-11-23 14:52:32

标签: asp.net-mvc asp.net-core middleware

我正在编写一个.Net核心中间件来加密查询字符串参数,我想让用户看到类似的内容 ?ENC = VXzal017xHwKKPolDWQJoLACDqQ0fE // wGkgvRTdG / GgXIBDd1 虽然代码看到了这一点 ?用户= 123&安培;帐户= 456

我使用IDataProtector加密参数。我的中间件中的Invoke()看起来像下面的代码

if (UriHelper.GetEncodedUrl(context.Request).Contains("?"))
        {
            string query = ExtractQuery((context.Request.GetEncodedUrl()));

            int indexOfEnc = query.IndexOf(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase);

            if (indexOfEnc > -1)
            {

                var enc = context.Request.Query[PARAMETER_NAME];
                enc = Decrypt(enc);
                context.Request.Path = new PathString(context.Request.Path.Value + enc);
                await _next.Invoke(context);
            }

            else if (context.Request.Method == "GET" || context.Request.Method == "POST")
            {
                // Encrypt the query string and redirects to the encrypted URL.
                // Remove if you don't want all query strings to be encrypted automatically.
                string encryptedQuery = Encrypt(query);
                string tempRawUrl = UriHelper.GetEncodedUrl(context.Request).ToLower();
                if (!(context.Request.Method == "POST" && tempRawUrl.Contains("ha")))
                {
                    context.Response.Redirect(context.Request.Path.Value + "?" + PARAMETER_NAME +  "=" + encryptedQuery);
                }
            }

        }
        else
        {
            await _next.Invoke(context);
        }

我第一次登录并输入用户/通行证时,代码会进入上面的elseif部分并加密。我下次寻找“enc”查询参数,当它被解密并且路径看起来很好时,

**await _next.Invoke(context);**
if部分中的

什么都不做。我期待它去控制器验证用户/通行证。

请在这里与我联系,这是我的第一个中间件,我正在尝试替换遗留代码中的httphandlers。

感谢任何帮助。我花了差不多5个小时,似乎无法弄明白。

2 个答案:

答案 0 :(得分:1)

您可以查看IQueryFeatureIResponseFeature。在ASP.NET Core中,功能允许覆盖基础对象的行为 喜欢HttpRequest& HttpResponse对象。

您可以简单地将现有IQueryFeature换行以进行透明解密。 对于查询加密,请将现有IResponseFeature包装为透明加密。 在中间件中设置包装器。

httpContext.Features.Set<IQueryFeature>(new TransparentDecryptionQueryFeature(httpContext.Features.Get<IQueryFeature>));
httpContext.Features.Set<IResponseFeature>(new TransparentEncryptionResponseFeature(httpContext.Features.Get<IResponseFeature>));

通过这样做,所有在您之后执行的中间件将使用“透明功能”。

public class TransparentDecryptionQueryFeature : IQueryFeature
{
    privare readonly IQueryCollection _store;

    public TransparentDecryptionQueryFeature(IQueryFeature feature)
    {
        _store = new TranparentDecryptionQueryCollection(feature.Query);
    }

    public IQueryCollection Query
    {
        get
        {
            return _store;
        }

        set
        {
            _store = new TransparentDecryptionQueryCollection(value);
        }
    }
}

public class TransparentDecryptionQueryCollection : IQueryCollection
{
    private readonly IQueryCollection _inner;

    public TransparentDecryptionQueryCollection(IQueryCollection inner)
    {
         var store = new Dictionary<string, StringValues>()
         foreach (var item in inner)
         {
             if (item.Key == PARAMETER_NAME)
             {
                 // TODO : Adds all the decrypted query parameters in the store
             }
             else
             {
                 store.Add(item);
             }
         }
         _inner = new QueryCollection(store);
    }

    // implement other methods by delegating with _inner object
}

答案 1 :(得分:0)

我将代码更改为。

if (indexOfEnc > -1)
            {

                var enc = context.Request.Query[PARAMETER_NAME];
                enc = "?" + Decrypt(enc);
                Microsoft.AspNetCore.Http.QueryString queryString = new Microsoft.AspNetCore.Http.QueryString(enc);
                    context.Request.QueryString = queryString;

                await _next.Invoke(context);
            }

现在确实有效。我仍然认为我在这里遗漏了一些东西。有更好的方法吗?