我正在编写一个.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个小时,似乎无法弄明白。
答案 0 :(得分:1)
您可以查看IQueryFeature
和IResponseFeature
。在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);
}
现在确实有效。我仍然认为我在这里遗漏了一些东西。有更好的方法吗?