前沿:最近有個需求,出於安全方面的考慮,需要將請求和響應資料進行加密傳輸
最終請求如圖所示:
請求是Json資料,包括appKey,query和signkey欄位,響應欄位包括state,data,msg,version,signKey需要補充說明的就是加密方式。query和data的資料是用AES加密的,signKey是rsa加密的是AES的金鑰。
針對這種情況,利用中介軟體來處理請求響應流是最好不過了。
於是開始自己搗鼓httpContext。Request。Body和httpContext。Response。Body,發現讀取了request。Body後 想要再向起寫入資料就不行了。然後得到各路大神相助,這裡感謝@碼農*白難度的幫助,參考了他提的issue,最終解決了。程式碼如下:
public
class
EncryptDecryptMiddleware
{
private
readonly
RequestDelegate
_next
;
public
EncryptDecryptMiddleware
(
RequestDelegate
next
)
{
_next
=
next
;
}
public
async
Task
Invoke
(
HttpContext
httpContext
)
{
//判斷是否為加密請求
if
(
httpContext
。
Request
。
Headers
。
ContainsKey
(
“aesrequest”
))
{
//建立http的原始請求和響應流
var
reqOrigin
=
httpContext
。
Request
。
Body
;
var
resOrigin
=
httpContext
。
Response
。
Body
;
try
{
using
(
var
newReq
=
new
MemoryStream
())
{
//替換request 流
httpContext
。
Request
。
Body
=
newReq
;
using
(
var
newRes
=
new
MemoryStream
())
{
//替換response流
httpContext
。
Response
。
Body
=
newRes
;
string
reqStr
;
using
(
var
streamReader
=
new
StreamReader
(
reqOrigin
))
{
//讀取原始請求的流的內容
reqStr
=
streamReader
。
ReadToEnd
();
}
//假設這裡對讀取的內容進行解密
string
writeStr
=
JsonConvert
。
SerializeObject
(
new
{
Name
=
“test”
});
//解密完之後把解密後內容寫入新的request流去
using
(
var
streamWriter
=
new
StreamWriter
(
newReq
))
{
streamWriter
。
Write
(
writeStr
);
streamWriter
。
Flush
();
//此處一定要設定=0,否則controller的action裡模型繫結不了資料
newReq
。
Position
=
0
;
//進入action
await
_next
(
httpContext
);
}
string
resStr
;
//讀取action返回的結果
using
(
var
streamReader
=
new
StreamReader
(
newRes
))
{
newRes
。
Position
=
0
;
resStr
=
streamReader
。
ReadToEnd
();
}
//假設這裡對action返回的結果進行加密
string
resWriteStr
=
“hello world”
;
using
(
var
streamWriter
=
new
StreamWriter
(
resOrigin
))
{
streamWriter
。
Write
(
resWriteStr
);
}
}
}
}
finally
{
//將原始的請求和響應流替換回去
httpContext
。
Request
。
Body
=
reqOrigin
;
httpContext
。
Response
。
Body
=
resOrigin
;
}
}
else
{
await
httpContext
。
Response
。
WriteAsync
(
“don‘t receive non-encrpt request”
);
}
}
}
好了,程式碼就是這樣,希望能夠對有類似這樣需求的人有幫助,註釋很詳細了,如果其他問題可以私信我。