客戶端訪問上游API服務,通常由Kong的認證插件及其配置參數來控制。
通用認證
一般情況下,上游API服務都需要客戶端有身份認證,且不允許錯誤的認證或無認證的請求通過。認證插件可以實現這一需求。這些插件的通用方案/流程如下:
1、向一個API或全局添加AUTH插件(此插件不作用於consumers);
2、常見一個consumer對象;
3、為consumer提供指定的驗證插件方案的身份驗證憑據;
4、現在,只要有請求進入Kong,都將檢查其提供的身份驗證憑據(取決於auth類型),如果該請求無法被驗證或者驗證失敗,則請求會被鎖定,不執行向上有服務轉發的操作。
但是,上述的一般流程並不是總是有效的。譬如,當使用了外部驗證方案(比如LDAP)時,KONG就不會(不需要)對consumer進行身份驗證。
Consumers
最簡單的理解和配置consumer的方式是,將其於用戶進行一一映射,即一個consumer代表一個用戶(或應用)。但是對於KONG而言,這些都無所謂。consumer的核心原則是你可以為其添加插件,從而自定義他的請求行為。所以,或許你會有一個手機APP應用,並為他的每個版本都定義一個consumer,又或者你又一個應用或幾個應用,並為這些應用定義統一個consumer,這些都無所謂。這是一個模糊的概念,他叫做consumer,而不是user!萬萬要區分開來,且不可混淆。
匿名訪問
在Kong 0.10.x版本之前,你可以將指定的API配置為僅允許經過身份驗證的訪問(通過插件來實現)或只允許匿名訪問。也就是說,一個指定的API,不允許對於某些consumer實行身份驗證,而對於另外的consumer實行匿名訪問。
在0.10.x版本以后,這些限制取消了--同一個API可以同時實現驗證和匿名兩種訪問方式。你可以使用他的這種特性,為一個API提供兩種服務方式:以較低的速率提供匿名訪問權限,以較高的速率實現驗證訪問權限。為指定API提供一個用戶試用體驗。
要配置這樣的API,您首先應用所選的認證插件,然后創建一個新的consumer來表示匿名用戶,然后配置你的身份驗證插件以允許匿名訪問。這里有一個示例,它假設您已經配置了一個名為example-api的API:
1、創建example-api:
$ curl -i -X POST \ --url http://localhost:8001/apis/ \ --data 'name=example-api' \ --data 'uris=/auth-sample' \ --data 'upstream_url=http://mockbin.org/request'
此時,無論什么樣的請求,http://localhost:8000/auth-sample 都會有輸出信息。
2、配置 key-auth 插件:
$ curl -i -X POST \ --url http://localhost:8001/apis/example-api/plugins/ \ --data 'name=key-auth'
3、驗證 key-auth 插件是否正確配置:
$ curl -i -X GET \ --url http://localhost:8000/auth-example
此時,由於你並未在請求參數或請求頭里使用apikey,所以這個請求會報403錯誤:
HTTP/1.1 403 Forbidden ... { "message": "No API key found in headers or querystring" }
4、創建一個匿名consumer:
每一次的KONG的代理請求,都會有一個對應的consumer對象。這里創建一個anonymous_consumer來測試API的匿名請求:
$ curl -i -X POST \ --url http://localhost:8001/consumers/ \ --data "username=anonymous_users"
你會得到以下的返回信息:
HTTP/1.1 201 Created Content-Type: application/json Connection: keep-alive { "username": "anonymous_users", "created_at": 1428555626000, "id": "bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9" }
5、開啟API的匿名請求:
您現在將重新配置密鑰驗證插件,以允許匿名訪問:
$ curl -i -X PATCH \ --url http://localhost:8001/apis/example-api/plugins/4a223b63-c44a-40e5-9102-b23335f594ca \ --data "config.anonymous=bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9"
這里的兩個uuid,分別是第2步和第4步中產生的uuid。具體請參考兩步操作中返回參數id。
config.anonymous = <consumer uuid>參數表示該API上的密鑰驗證插件允許匿名訪問,並將此訪問與上一步中收到的consumer的ID相關聯。在此步驟中,您需要提供有效的consumerID - 當進行匿名配置時,不會對consumer的id進行檢驗,如果配置了一個不存在的或錯誤的consumerid,則會導致插件不能正常運行。
6、驗證匿名訪問:
$ curl -i -X GET \ --url http://localhost:8000/auth-sample
這個訪問請求和第三步中的一樣,然而,此時的訪問是通過的,只因為你在第五步中配置了匿名訪問。返回內容大致是:
{ ... "headers": { ... "x-consumer-id": "713c592c-38b8-4f5b-976f-1bd2b8069494", "x-consumer-username": "anonymous_users", "x-anonymous-consumer": "true", ... }, ... }
這顯示,請求通過了,並且是以匿名的方式。
多重驗證
Kong 0.10.x擴展了為給定API應用多個驗證插件的能力,並允許不同的客戶端使用不同的身份驗證方法來訪問給定的API服務。在評估多個身份驗證憑據時,可以將驗證插件的行為設置為邏輯AND或邏輯OR。該行為的關鍵是配置config.anonymous屬性。
· config.anonymous 默認為未設置。如果此屬性未設置(空),則auth插件將始終執行身份驗證,並返回40x響應(如果未驗證)。當調用多個驗證插件時,會導致邏輯AND。
· config.anonymous 設置為有效的consumer ID。在這種情況下,auth插件只有在尚未認證的情況下才會執行身份驗證。當身份驗證失敗時,它不會返回40x響應,而是將匿名consumer設置為consumer。當調用多個驗證插件時,會使用OR+匿名。
備注1:所有的或任何一個驗證插件都可配置為可使匿名訪問的。但是,如果要混合使用驗證插件,則對於匿名訪問的配置就需要進行甄選,否則會出現混亂。
備注2:如果使用AND邏輯,則最后一個執行的驗證插件將是把驗證信息傳遞給上游服務的那個。當使用OR邏輯時,傳遞給上游服務驗證信息的那個插件,將會是第一個成功驗證consumer的那個插件,或者是最后一個配置了匿名訪問權限的那個插件。
ps:如果對API使用多個驗證插件,且插件間的邏輯配置為OR的話,最好不要為每個插件開啟匿名訪問,這樣才能保證最終能成功請求的consumer是預期的那個。否則會有不可預期的結果出現。