前沿:最近有個需求,出於安全方面的考慮,需要將請求和響應資料進行加密傳輸

最終請求如圖所示:

Asp.Net Core中介軟體攔截Http流

請求是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”

);

}

}

}

好了,程式碼就是這樣,希望能夠對有類似這樣需求的人有幫助,註釋很詳細了,如果其他問題可以私信我。