緣起
如題,想要用geoserver實現一個網際網路地圖那樣的key許可功能,來控制地圖服務的訪問許可權。
最終想要的效果就是類似下圖中百度地圖那樣,申請個key,可以設定這個key能訪問哪些地圖服務資源,可以設定應用伺服器ip白名單
然後把key放到地圖API中,就能控制地圖服務的訪問許可權。
可行性分析
要使用geoserver實現上述功能,需要解決下面3個問題:
- 如何實現key驗證訪問?
- 如何控制key能訪問哪些地圖服務?
- 如何實現伺服器ip白名單?
如何實現key驗證訪問
geoserver釋出的地圖服務,預設沒有進行許可權控制,任何人拿到地址都可以訪問地圖。
我們想要的效果是,在訪問geoserver服務時,需要在引數中增加一個key的引數,有這個key才能訪問地圖。
這個功能,geoserver是支援的
geoserver有個AuthKey的外掛,支援接入外部的身份驗證介面,我們可以通過自己編寫外部的身份驗證介面,來自己生成key、驗證key,geoserver只負責轉發和獲取驗證結果。外部介面返回的是geoserver使用者名稱稱。
然後再設定一下geoserver的攔截器,規定哪些請求必須要進行上面的驗證。
如何控制key能訪問哪些地圖服務?
key的訪問許可權是通過geoserver使用者的訪問許可權來設定的,前面驗證key時,已經返回了使用者名稱。
使用者的許可權通過角色控制,所以每次建立key時,需要同時建立使用者和角色,並設定角色的訪問許可權。
這個環節可以使用geoserver的rest控制介面解決,使用rest控制介面可以通過程式自動完成上述配置。
如何實現伺服器ip白名單
geoserver 作為一個服務端,它只能獲取到客戶端的ip,無法獲取到應用伺服器的ip。
如果想要獲取的應用伺服器的ip,就需要前端有個內應,這個內應就是js地圖api,它可以在客戶端的位址列中獲取到應用伺服器的ip,然後傳給服務端。
具體到geoserver這邊,我們還是利用前面外部驗證介面,在js地圖Api中,把位址列獲取到的應用伺服器ip和key拼一起,通過 AuthKey 的外部驗證介面轉發給自己的後臺,後臺再將ip提取出來。
位址列ip和key的拼接,可以使用公鑰、私鑰模式,js地圖api中使用公鑰加密,後臺使用私鑰解密,這樣可以避免明文傳輸ip地址。防止別人串改ip後非法訪問地圖。
這樣就能實現對應用伺服器ip的驗證了。
流程梳理
好了,現在我們已經完成了可行性分析
接下來我們梳理一下,申請key和使用key訪問地圖的流程。
申請key
- 在申請地圖key的頁面,輸入應用名稱、應用部署的伺服器ip、勾選需要的地圖服務,然後生成個key
- 呼叫geoserver的rest控制介面,建立角色、使用者、設定角色可以訪問的地圖服務
- 將key、應用伺服器ip和geoserver使用者進行關聯並儲存到資料庫
訪問地圖
- 開發地圖應用時,把申請到的key傳入自己寫的js地圖api
- js地圖api內部獲取瀏覽器位址列ip,這個ip就是應用伺服器ip,將ip和key使用公鑰加密,生成newkey,並在請求geoserver服務時將newkey作為引數傳給geoserver
- geoserver的攔截器攔截到請求後,將newkey提取出來,轉發給我們自己寫的許可權驗證介面
- 許可權驗證介面接收到newkey後,使用私鑰解密,就能獲取到key和應用伺服器ip,然後去資料庫比對是否有符合這兩個條件的資料,如果有就返回對應的geoserver使用者名稱
- geoserver攔截器接收到驗證介面返回的使用者名稱後,查詢該使用者擁有的角色,再比對角色的許可權中是否有本次請求的地圖服務。有就返回資料,沒有就打回。
這樣一整套流程下來,就實現了用geoserver,實現類似網際網路地圖那樣的key驗證方式來控制地圖的訪問許可權
實施步驟
接下來詳細介紹一下攔截器設定和使用者許可權設定。
geoserver的攔截器設定一次就行。
key、使用者、角色是一一對應的,所以每次新增key時,都要去通過rest介面去新建使用者和角色並設定角色的地圖訪問許可權。
攔截器設定
這一步其實就是通過介面來配置geoserver的攔截器,分兩步,一是配置訪問哪些地址時進行攔截,也就是配置攔截規則,二是配置攔截下來後驗證key是否有效,也就是配置驗證規則
具體操作為先配置驗證規則,再將驗證規則新增攔截規則中
配置key驗證規則
按下圖操作
低版本geoserver可能沒有authkey功能,需要去官網下載對應版本的
Key authentication
外掛並手動安裝
點選AuthKey後,會出現下圖中的介面
“1”那裡自己隨便填一個,比如就叫做uuid_authkey
。
“2”那裡選擇webservice
。這個選項的意思是,geoserver會使用外部介面驗證key是否有效,到時geoserver會通過get方式將key傳給外部介面,外部介面負責驗證key是否有效,如果有效就返回使用者名稱。
“3”那裡配置外部介面的呼叫地址,geoserver呼叫時,會自動將{key}
換成真實的key
其它選項保持預設就可以
我用java寫了個外部介面的示意程式碼,來大概說明一下里面的邏輯,其實就是根據key獲取geoserver使用者名稱
身份驗證設定完以後點選儲存按鈕,它就會出現在下面的列表中。
配置服務攔截規則
接下來我們配置攔截規則,配置介面如下圖:
我們點選最下面的 default
把我們剛才設定的身份驗證規則新增到 anonymous
規則前面
這個列表從上到下是身份驗證的先後順序,
anonymous
的意思是任何人可以匿名訪問,如果把我們新增的規則放到了anonymous
的後面,就不會起作用了。
default
裡面能攔截wms和wfs請求,但不會攔截wmts和tms請求,我們需要新建一個規則,用來攔截wmts和tms請求。
wmts和tms屬於瓦片快取,歸geowebcache管理,geowebcache的網路請求地址為 gwc
,所以我們新建攔截規則時,規則設定為/gwc/**
,然後將我們的uuid_authkey
使用者驗證規則新增上,名稱隨便填一個,比如 tile
,如下圖:
注意:這個頁面沒有儲存按鈕,編輯後需要返回上一個介面進行儲存。
新增完成後,調整 tile
規則的位置,放到 default
上面,然後儲存。
這樣就實現了geoserver的key驗證。
使用者許可權設定
這裡直接列出需要使用的rest介面地址
使用rest介面時要注意兩點:
1、geoserver的rest介面原則上支援xml和json格式的引數,但實際不一定,如果你用其中一種格式沒有成功,這時不要吊死在一棵樹上,可以換個格式試試。我就遇到了在新增使用者時xml格式好使json格式不好使,但在設定許可權時xml格式又不好使,json格式好使。
2、設定角色訪問許可權
介面的引數和文件介紹的有所不同,這裡要注意一下,正確的是下面這種:
{
"workspace.*.r": "rolename"
}
geoserver的rest介面說明:https://www.osgeo.cn/geoserver-user-manual/rest/index.html#rest
我用 Postman 匯出了一份兒 java Unirest 的程式碼,供大家參考:http://gisarmory.xyz/blog/index.html?source=geosreverAuthkey
總結
- geoserver使用者許可權不僅支援對管理介面的控制,還支援對地圖服務請求的控制
- 地圖服務的控制需要結合key驗證的方式實現,通過配置geoserver的攔截器和驗證規則,可以把key和使用者關聯起來
- geoserver只支援對客戶端ip的驗證,想要驗證應用伺服器的ip,需要藉助js地圖api實現
參考資料:
- https://blog.csdn.net/a571574085/article/details/115659432
- https://blog.csdn.net/qq_38000851/article/details/113870725
- https://www.cnblogs.com/defineconst/p/13884616.html
- https://www.cnblogs.com/HandyLi/p/8624507.html
- https://www.osgeo.cn/geoserver-user-manual/extensions/geofence-server/index.html
- https://www.osgeo.cn/geoserver-user-manual/rest/index.html#rest
- https://github.com/geoserver/geofence
原文地址:http://gisarmory.xyz/blog/index.html?blog=geosreverAuthkey
歡迎關注《GIS兵器庫》
本文章採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名《GIS兵器庫》(包含連結: http://gisarmory.xyz/blog/),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。