基于http协议的api接口对于客户端的身份认证方式以及安全措施
? ? 由于http是無狀態(tài)的,所以正常情況下在瀏覽器瀏覽網(wǎng)頁,服務(wù)器都是通過訪問者的cookie(cookie中存儲(chǔ)的jsessionid)來辨別客戶端的身份的,當(dāng)客戶端進(jìn)行登錄服務(wù)器也會(huì)將登錄信息存放在服務(wù)器并與客戶端的cookie中的jsessionid關(guān)聯(lián)起來,這樣客戶端再次訪問我們就可以識(shí)別用戶身份了。
? ? 但是對(duì)于api服務(wù)器,我們不能讓訪問者先登錄再進(jìn)行訪問這樣不安全,也不友好。所以一般情況我們都是需要客戶端提供一個(gè)key(每個(gè)key跟用戶是一對(duì)一關(guān)聯(lián)的)來識(shí)別請(qǐng)求者的身份。
? ? 由HTTP協(xié)議進(jìn)行通信的數(shù)據(jù)大都是未經(jīng)加密的明文,包括請(qǐng)求參數(shù)、返回值、 cookie、 head等等數(shù)據(jù),因此,外界通過對(duì)通信的監(jiān)聽,輕而易舉便可根據(jù)請(qǐng)求和響應(yīng)雙方的格式,偽造請(qǐng)求與響應(yīng),修改和竊取各種信息。所以我們還需要對(duì)每次請(qǐng)求進(jìn)行認(rèn)證,來判斷發(fā)起請(qǐng)求的是不是就是該用戶,以及請(qǐng)求信息是否被篡改。一般采用對(duì)請(qǐng)求信息(請(qǐng)求uri,參數(shù))進(jìn)行摘要的方法來解決上述問題。由于摘要算法的不可逆性,因此這種方式能夠在一定程度上防止信息被篡改,保障通信的安全。
1、MD5方式
用戶需要先在網(wǎng)站上申請(qǐng)key、secret,然后校驗(yàn)流程如下:
客戶端:
1.參數(shù)排序
2.將參數(shù)串接起來加上secret,生成待摘要字符串
3.使用MD5等摘要算法生成摘要串signature
4.將key,signature放入header中一并傳給服務(wù)器
服務(wù)器:
1.參數(shù)排序?
2.將參數(shù)串接起來加上secret(通過header中的key在數(shù)據(jù)庫獲取),生成待摘要字符串?
3.使用MD5等摘要算法生成摘要串?
4.服務(wù)端生成的摘要串與客戶端通過header傳遞過來的摘要串進(jìn)行比較
?
2、HmacSHA256方式
用戶需要先在網(wǎng)站上申請(qǐng)key、secret,然后校驗(yàn)流程如下:
客戶單:
1.將請(qǐng)求參數(shù)封裝成json字符串,也就是請(qǐng)求體body
2.使用HmacSHA256算法加secret對(duì)(請(qǐng)求url+nonce+body)加密生成摘要signature??
3.將key,signature放入header中一并傳給服務(wù)器
服務(wù)器:
1.獲取請(qǐng)求中的請(qǐng)求體body字符串
2.使用HmacSHA256算法加secret(通過header中的key在數(shù)據(jù)庫獲取)對(duì)(請(qǐng)求url+nonce+body)加密生成摘要signature?
3.服務(wù)端生成的摘要串與客戶端通過header傳遞過來的摘要串進(jìn)行比較
注意使用HmacSHA256更加安全,而且我們可以直接將請(qǐng)求參數(shù)封裝成json字符串放入請(qǐng)求體中(也就是通過io流)進(jìn)行傳遞。
?
實(shí)際使用中遇到的問題:
1、帶有下劃線的header被過濾
? ? 當(dāng)我們?cè)谑褂肏macSHA256進(jìn)行認(rèn)證的時(shí)候,需要客戶端將請(qǐng)求key,signature放入header,name設(shè)置為api_key,api_signature,這時(shí)出現(xiàn)一個(gè)問題是服務(wù)器怎么都獲取不到這兩個(gè)值,但是我在本機(jī)測(cè)試時(shí)沒有問題的。后來才想起來是不是由于使用nginx做集群而部分頭被過濾了,查看過后果然是nginx將帶有下劃線的header name過濾了,后來修改nginx配置便可以正常獲取頭信息。不過后來服務(wù)器使用了第三方的動(dòng)態(tài)加速再次把帶有下劃線的header name給過濾了,為了避免麻煩索性修改程序?qū)eader name中的下劃線都去掉了。
2、確保每次請(qǐng)求唯一性
? ? 由于http都是明文請(qǐng)求,雖然我們可以通過摘要進(jìn)行一定的安全保證確保信息不被篡改,但是我們無法保證每次請(qǐng)求的唯一性,也就是如果請(qǐng)求數(shù)據(jù)被別人獲取再次請(qǐng)求,此時(shí)也可能帶來很嚴(yán)重的安全性問題。于是我們便需要用戶在每次請(qǐng)求中設(shè)置一個(gè)遞增的參數(shù)nonce,來確保每次請(qǐng)求都是唯一的。不過這樣也可能帶來一個(gè)問題,就是如果用戶近乎同時(shí)發(fā)起兩個(gè)請(qǐng)求a b,由于網(wǎng)絡(luò)阻塞,可能后發(fā)起的b先到達(dá)服務(wù)器,這樣當(dāng)a達(dá)到的時(shí)候,服務(wù)器會(huì)認(rèn)為a的nonce已過期請(qǐng)求非法而拒絕。為了解決這樣的問題我們?cè)试S用戶設(shè)置一個(gè)expire值來避免nonce認(rèn)證帶來的問題。
3、SNI
? ? 由于當(dāng)時(shí)我們有不同的工程(不同的域名,跟不同的證書)位于同一臺(tái)服務(wù)器,這樣有的客戶端訪問我們api工程會(huì)拋異常,說http握手失敗或者說請(qǐng)求域名與服務(wù)器證書不匹配而失敗。所以我們需要客戶端程序支持sni,它允許客戶端在發(fā)起SSL握手請(qǐng)求時(shí)(具體說來,是客戶端發(fā)出SSL請(qǐng)求中的ClientHello階段),就提交請(qǐng)求的Host信息,使得服務(wù)器能夠切換到正確的域并返回相應(yīng)的證書。對(duì)于java語言來說jdk7的后續(xù)版本已經(jīng)支持sni,或者使用httpclient 4.3及以后版本都可以很好的支持sni了。
?
轉(zhuǎn)載于:https://www.cnblogs.com/gmou/p/4458754.html
總結(jié)
以上是生活随笔為你收集整理的基于http协议的api接口对于客户端的身份认证方式以及安全措施的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ 2299 Ultra-Quick
- 下一篇: STM8L探索套件学习笔记(转)