簡(jiǎn)化微服務(wù)驗(yàn)證的新方法:開(kāi)放式策略代理(OPA)
譯文【51CTO.com快譯】從概念上說(shuō),身份驗(yàn)證是指識(shí)別出用戶是誰(shuí),而授權(quán)是指確定某個(gè)已被認(rèn)證用戶具有的何種訪問(wèn)級(jí)別。不知您是否注意到:由于分布式應(yīng)用往往難以實(shí)現(xiàn)強(qiáng)大、且集中式管理所需的身份驗(yàn)證和授權(quán)(Authentication and Authorization,A&A)策略,因此在微服務(wù)的實(shí)際應(yīng)用中,您可能時(shí)常會(huì)遇到驗(yàn)證和授權(quán)的實(shí)施問(wèn)題。下面,我將和您探討開(kāi)放式策略代理(Open Policy Agent,OPA)是如何協(xié)助簡(jiǎn)化授權(quán)問(wèn)題的。
為簡(jiǎn)單起見(jiàn),我創(chuàng)建了一個(gè)帶有多個(gè)微服務(wù)應(yīng)用示例。通過(guò)其基本的用戶界面,我們可以在其中執(zhí)行各項(xiàng)操作,并查看產(chǎn)生的結(jié)果。該應(yīng)用將向您展示開(kāi)放式策略代理是如何處理各種授權(quán)方案的。
應(yīng)用示例
在此,我們以銷(xiāo)售團(tuán)隊(duì)常用的、為客戶制定報(bào)價(jià)的CPQ(配置、定價(jià)和報(bào)價(jià))應(yīng)用(https://en.wikipedia.org/wiki/Configure,_price_and_quote)為例,定義并創(chuàng)建了如下角色:
- 銷(xiāo)售–作為銷(xiāo)售人員,他們可以為客戶創(chuàng)建并更新報(bào)價(jià)。但是不能刪除報(bào)價(jià)。
- 銷(xiāo)售支持–作為支持人員,他們可以查看所有報(bào)價(jià),但不能編輯任何報(bào)價(jià)。
- 銷(xiāo)售管理員–作為管理員,他們可以查看所有報(bào)價(jià),但不能編輯或創(chuàng)建任何報(bào)價(jià)。不過(guò),他們可以根據(jù)清理需求去刪除報(bào)價(jià)。
鑒于本文僅專(zhuān)注于授權(quán)環(huán)節(jié),在此,我們假設(shè)用戶已經(jīng)通過(guò)了身份驗(yàn)證,并且持有有效的JSON Web令牌(JWT)。而且每個(gè)API請(qǐng)求,都會(huì)在請(qǐng)求的頭部包含該JWT。
該示例應(yīng)用在GitHub的下載鏈接為--https://github.com/gchaware/opa-ms-sample/tree/master。請(qǐng)根據(jù)README的說(shuō)明,逐步進(jìn)行安裝,并通過(guò)URL--http://
執(zhí)行授權(quán)
根據(jù)上述角色分配,我們授權(quán)
- 銷(xiāo)售團(tuán)隊(duì)能夠創(chuàng)建新的報(bào)價(jià),查看報(bào)價(jià),以及更新現(xiàn)有報(bào)價(jià)。
- 銷(xiāo)售支持團(tuán)隊(duì)只能查看報(bào)價(jià),不能編輯或創(chuàng)建它們。
- 銷(xiāo)售管理團(tuán)隊(duì)既能夠查看報(bào)價(jià),又能夠刪除它們。
如上圖所示的UI顯示了多個(gè)按鈕,每個(gè)按鈕都代表用戶的一項(xiàng)操作。根據(jù)用戶選擇使用的角色,UI將會(huì)及時(shí)反饋創(chuàng)建、編輯或刪除商品操作成功與否的結(jié)果。
上圖展示了該應(yīng)用程序帶有兩個(gè)微服務(wù):Offer(報(bào)價(jià))和Customer(客戶)。通過(guò)將API向外界公布,NGINX反向代理能夠截獲每個(gè)API請(qǐng)求,并通過(guò)請(qǐng)求授權(quán)服務(wù),來(lái)驗(yàn)證是否允許用戶執(zhí)行該請(qǐng)求的相關(guān)操作。
在此,我們使用NGINX的auth_request指令,來(lái)截獲傳入的API調(diào)用。其中,每個(gè)API調(diào)用都有一個(gè)包含了JWT頭部的授權(quán)。而所有用戶的基本信息,包括其角色都被包含在JWT中。在此,該授權(quán)服務(wù)帶有兩個(gè)容器:
- Authorization(授權(quán))–作為已定制的授權(quán)服務(wù),可用于接收請(qǐng)求,并為下面的Open Policy Agent創(chuàng)建經(jīng)過(guò)格式化的輸入請(qǐng)求。
- Open Policy Agent (OPA,開(kāi)放策略代理)–作為輔助工具,它通過(guò)對(duì)外公布HTTP端點(diǎn),以實(shí)現(xiàn)與授權(quán)容器的通信。
首先,NGINX會(huì)將/authorize的請(qǐng)求發(fā)送給授權(quán)容器,以授權(quán)某個(gè)API調(diào)用。接著,授權(quán)服務(wù)會(huì)向開(kāi)放策略代理詢問(wèn)是否有授權(quán)請(qǐng)求(true/false)。然后,它向NGINX返回成功(200 OK)或者是失敗(403 Forbidden)的響應(yīng)。據(jù)此,NGINX或是允許API的調(diào)用,或是向客戶端返回403 Forbidden的響應(yīng)。
什么是開(kāi)放策略代理?
開(kāi)放策略代理(OPA)是一個(gè)開(kāi)源的通用策略引擎,它統(tǒng)一了整個(gè)棧中的策略執(zhí)行。OPA提供了一種高級(jí)聲明性的語(yǔ)言,可方便您將策略轉(zhuǎn)換為代碼和簡(jiǎn)單的API,進(jìn)而減輕了軟件在決策時(shí)的負(fù)擔(dān)。您可以在微服務(wù)、Kubernetes、CI/CD管道、以及API網(wǎng)關(guān)中,使用OPA來(lái)實(shí)施策略。
由于OPA能夠接受JSON之類(lèi)結(jié)構(gòu)化的數(shù)據(jù)作為輸入,并且可以返回true/false的決策,或?qū)⑷我饨Y(jié)構(gòu)化的數(shù)據(jù)作為輸出,因此它能夠有效地將決策與執(zhí)行予以脫鉤。
值得一提的是,OPA使用rego作為策略語(yǔ)言。您可以通過(guò)鏈接--https://www.openpolicyagent.org/docs/latest/,了解更多有關(guān)rego和開(kāi)放策略代理的信息。
詳述授權(quán)服務(wù)
下面讓我們來(lái)詳細(xì)討論授權(quán)服務(wù)的具體工作方式。
如上圖所示,我們?cè)诜?wù)器模式下運(yùn)行開(kāi)放策略代理,并利用其REST API的更新策略來(lái)獲取決策。如下命令展示了開(kāi)放策略代理通過(guò)對(duì)外公布REST API,來(lái)創(chuàng)建或更新策略。
- PUT /v1/policies/ Content-Type: text/plain
在本例中,我們需要端點(diǎn)接收如下的請(qǐng)求,來(lái)更新OPA中的策略(具體可參照它在GitHub里的README)。
- curl -X PUT --data-binary @policies/httpapi.authz.rego http:///authorize/v1/policies/httpapi/authz
同時(shí),我們需要另一個(gè)API來(lái)根據(jù)政策做出決策:
- POST /v1/data/
- Content-Type: application/json
此處的
- {
- "input" : {
- "method": "DELETE",
- "api": "/offer/1000",
- "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1NzQ2NjM3MDAsImV4cCI6NDA5OTE4NTMwMCwiYXVkIjoib3BhLWV4YW1wbGUuY29tIiwic3ViIjoianjvy2tldeblegftcgxllmnvbsisikdpdmvutmftzsi6ikpvag5uesisiln1cm5hbwuioijsb2nrzxqilcjfbwfpbci6impyb2nrzxrazxhhbxbszs5jb20iLCJSb2xlIjoiU2FsZXMgQWRtaW4ifQ._UtjZtowF3NNN3IF1t0LBHuzQhdfIfsO8jC-46GvbRM"
- }
- }
由代碼可知,授權(quán)應(yīng)用程序?qū)⑹盏綇腘GINX發(fā)來(lái)的請(qǐng)求,并根據(jù)上面的邏輯圖為OPA產(chǎn)生輸入請(qǐng)求。針對(duì)該示例,我們?cè)谇岸舜a中對(duì)JWT進(jìn)行了硬編碼。而且每個(gè)API請(qǐng)求都會(huì)在Authorization頭部包含JWT。據(jù)此,授權(quán)應(yīng)用程序在獲取JWT后,會(huì)將其添加到OPA的輸入請(qǐng)求中。其具體Java代碼如下:
- Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJMb2NhbEpXVElzc3VlciIsImlhdCI6MTU3MzcyNzM5MSwiZXhwIjo0MDk4MjQ1Mzc4LCJhdWQiOiJvcGEtZXhhbXBsZS5jb20iLCJzdWIiOiJzYWxlc0BleGFtcGxlLmNvbSIsIkdpdmVuTmFtdyI6IkpvaG5ueSIsIlN1cm5hbWUiOiJTYWxlcyIsIkVtYWlsIjoianNhbGVzQGV4YW1wbGUuY29tIiwiUm9sZSI6IlNhbGVzIn0.UbHWQpCMwupzsFp8f0CQ4o_bJSVaBugKijhcURZ_Mko
值得注意的是,授權(quán)服務(wù)只會(huì)從輸入的請(qǐng)求中檢索JWT,而不會(huì)對(duì)其進(jìn)行解碼。因此,OPA會(huì)通過(guò)內(nèi)置的io.jwt.decode功能函數(shù),去支持JWT的解析。
您可以通過(guò)鏈接--https://play.openpolicyagent.org/p/4LOvGaEXEU,進(jìn)一步了解rego策略的相關(guān)程序代碼與邏輯。通過(guò)嘗試不同的輸入請(qǐng)求,您將能夠查看到OPA為每一個(gè)請(qǐng)求所生成的不同輸出。
小結(jié)
綜上所述,開(kāi)放策略代理提供了一種將授權(quán)決策與微服務(wù)中的業(yè)務(wù)邏輯相分離的方法。在實(shí)際應(yīng)用中,系統(tǒng)管理員可以通過(guò)對(duì)開(kāi)放策略代理進(jìn)行設(shè)置,將生成授權(quán)策略(rego策略)的責(zé)任,委托給各個(gè)微服務(wù)的所有者。而微服務(wù)所有者和系統(tǒng)管理員都不會(huì)越界進(jìn)行任何處理。
原文標(biāo)題:Open Policy Agent: Microservices Authorization Simplified,作者:Gaurav Chaware
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】