geoserver控制服務訪問許可權-類似百度地圖的key

緣起

如題,想要用geoserver實現一個互聯網地圖那樣的key許可功能,來控制地圖服務的訪問許可權。

最終想要的效果就是類似下圖中百度地圖那樣,申請個key,可以設置這個key能訪問哪些地圖服務資源,可以設置應用伺服器ip白名單

然後把key放到地圖API中,就能控制地圖服務的訪問許可權。

可行性分析

要使用geoserver實現上述功能,需要解決下面3個問題:

  1. 如何實現key驗證訪問?
  2. 如何控制key能訪問哪些地圖服務?
  3. 如何實現伺服器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

  1. 在申請地圖key的頁面,輸入應用名稱、應用部署的伺服器ip、勾選需要的地圖服務,然後生成個key
  2. 調用geoserver的rest控制介面,創建角色、用戶、設置角色可以訪問的地圖服務
  3. 將key、應用伺服器ip和geoserver用戶進行關聯並保存到資料庫

訪問地圖

  1. 開發地圖應用時,把申請到的key傳入自己寫的js地圖api
  2. js地圖api內部獲取瀏覽器地址欄ip,這個ip就是應用伺服器ip,將ip和key使用公鑰加密,生成newkey,並在請求geoserver服務時將newkey作為參數傳給geoserver
  3. geoserver的攔截器攔截到請求後,將newkey提取出來,轉發給我們自己寫的許可權驗證介面
  4. 許可權驗證介面接收到newkey後,使用私鑰解密,就能獲取到key和應用伺服器ip,然後去資料庫比對是否有符合這兩個條件的數據,如果有就返回對應的geoserver用戶名
  5. 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介面地址

名稱 地址
添加角色 //127.0.0.1:7200/geoserver/rest/security/roles/role/{role}
添加用戶 //127.0.0.1:7200/geoserver/rest/security/usergroup/users/
用戶指定角色 //127.0.0.1:7200/geoserver/rest/security/roles/role/{role}/user/{user}
設置角色訪問許可權 //127.0.0.1:7200/geoserver/rest/security/acl/layers

使用rest介面時要注意兩點:

1、geoserver的rest介面原則上支援xml和json格式的參數,但實際不一定,如果你用其中一種格式沒有成功,這時不要弔死在一棵樹上,可以換個格式試試。我就遇到了在添加用戶時xml格式好使json格式不好使,但在設置許可權時xml格式又不好使,json格式好使。

2、設置角色訪問許可權介面的參數和文檔介紹的有所不同,這裡要注意一下,正確的是下面這種:

{
    "workspace.*.r": "rolename"
}

geoserver的rest介面說明://www.osgeo.cn/geoserver-user-manual/rest/index.html#rest

我用 Postman 導出了一份兒 java Unirest 的程式碼,供大家參考://gisarmory.xyz/blog/index.html?source=geosreverAuthkey

總結

  1. geoserver用戶許可權不僅支援對管理介面的控制,還支援對地圖服務請求的控制
  2. 地圖服務的控制需要結合key驗證的方式實現,通過配置geoserver的攔截器和驗證規則,可以把key和用戶關聯起來
  3. geoserver只支援對客戶端ip的驗證,想要驗證應用伺服器的ip,需要藉助js地圖api實現

參考資料:

  1. //blog.csdn.net/a571574085/article/details/115659432
  2. //blog.csdn.net/qq_38000851/article/details/113870725
  3. //www.cnblogs.com/defineconst/p/13884616.html
  4. //www.cnblogs.com/HandyLi/p/8624507.html
  5. //www.osgeo.cn/geoserver-user-manual/extensions/geofence-server/index.html
  6. //www.osgeo.cn/geoserver-user-manual/rest/index.html#rest
  7. //github.com/geoserver/geofence

原文地址://gisarmory.xyz/blog/index.html?blog=geosreverAuthkey

歡迎關注《GIS兵器庫

本文章採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名《GIS兵器庫》(包含鏈接:  //gisarmory.xyz/blog/),不得用於商業目的,基於本文修改後的作品務必以相同的許可發布。