第四章、 研究成果: 系統實作與測試
2、 系統實作
2.1 資料加密傳輸
由於 Django Web Server 不支援 HTTPS,因此透過 Stunnel 套件於 Django Server 上建立 SSL 通道以支援 HTTPS,其中也藉由 OpenSSL 建立 X.509 SSL 憑 證(Certificate)與私鑰(Private Key)提供 Stunnel 加密通道使用。在憑證方面,本系 統以自己作為最高層認證中心(Root CA),並自己簽發屬於自己認證中心的信任 憑證,即根憑證或稱自簽憑證(Self-signed certificate)。因此透過上述機制使得 網路資料皆以 SSL 加密進行傳輸,可確保資料傳輸上的安全性。實作步驟如下:
(1). 於 Django Server 上安裝 Stunnel,作為 https proxy server。
$apt-get install stunnel4
(2). 建立有效期為 365 天的 X.509 憑證與私鑰。
$openssl req -new -x509 -days 365 -out /stunnel/stunnel.pem -keyout /stunnel/stunnel.pem
(3). 於 Django 專案下建立 dev_https,並設定憑證位置與 Stunnel 監聽的 port(accept),以及最後轉送至 port(connect)的 Django Server,如下:
cert = stunnel/stunnel.pem [https]
accept=443 connect=8001
(4). 啟動 Stunnel 與 Django Server
$stunnel4 stunnel/dev_https & HTTPS=on python manage.py runserver 0.0.0.0:8001 ( 即 可 瀏 覽
https://ictaaa.nccu.edu.tw/Auth/xxx)
2.2 混合雲帳號整合 ( 1 ). 一次性帳號對應之實作
首先使用者註冊其系統帳號、密碼、手機號碼,系統透過 Keystone 提供之 Identity API v3 之 User Create 介面建立一筆新的使用者帳號資訊(帳號、密碼)於 OpenLDAP 中,並透過手機驗證來確認該手機號碼的合法性,接著以系統帳號作 為唯一識別在帳號對應表中,建立該使用者的帳號對應紀錄,完成使用者系統註 冊。
完成註冊後,使用者向系統提供其公、私有雲或本地端帳號密碼作認領,系 統根據帳號的來源進行不同的帳號驗證方式(如: OpenID Connect 驗證、Hadoop Kerberos 驗證、OpenStack Keystone 驗證、本地端驗證)來確認帳號的合法性。
最後系統將各端合法帳號與密碼全部對應至該使用者之帳號對應紀錄中,完成一 次性帳號對應。以虛擬碼(pseudo code)描述如下: (圖四十)
圖 四十:一次性帳號對應之實作虛擬碼
針對虛擬碼中,系統在手機驗證、OpenID Connect 驗證、Hadoop Kerberos
驗證、OpenStack Keystone 驗證之實作細節,將於下面混合雲帳號驗證作說明。
( 2 ). 階段式帳號對應之實作
使用者於帳號對應管理介面進行帳號對應的新增,系統將根據使用者新增帳 號對應的方式進行不同的帳號驗證機制,來確認帳號的合法性。例如: 若使用者 以認領帳號的方式作新增,則系統將比照一次性帳號對應之帳號驗證機制進行驗 證 ; 若使用者以非認領帳號的方式作新增,則系統將直接把使用者導向公、私 有雲驗證頁面或本地端驗證頁面進行登入完成驗證。最後系統將該認領之合法帳 號與密碼或非認領之合法帳號對應至該使用者之帳號對應紀錄中,完成階段式帳 號對應。以虛擬碼(pseudo code)描述如下: (圖四十一)
圖 四十一:階段式帳號對應之實作虛擬碼
針對虛擬碼中,系統在 OpenID Connect 驗證、Hadoop Kerberos 驗證、
OpenStack Keystone 驗證之實作細節,將於下面混合雲帳號驗證作說明。
2.3 混合雲單一登入 ( 1 ). 帳號驗證之實作
系統以 Keystone 驗證元件作為帳號驗證之基礎,並透過 Keystone 提供之 Identity API v2.0 與 Identity API v3 驗證介面,完成對使用者帳號的驗證。其中使 用者能夠以系統帳號或已認領之各雲端及本地端帳號作登入,系統將根據使用者 提供的帳號類型的不同,而採取不同的帳號驗證機制(如: Keystone 帳號密碼驗證 機制、Keystone 外部驗證機制),並且以驗證後產生之 Keystone Token 作為系統 頒發給通過驗證使用者的 Token。以虛擬碼(pseudo code)描述如下:(圖四十二)
圖 四十二:帳號驗證實作之虛擬碼
針對虛擬碼中,系統採用之帳號密碼驗證機制與外部驗證機制之實作細節描 述如下:
(1). 帳號密碼驗證機制(user/password)
系統的帳號驗證模組接收到使用者的系統帳號與密碼,向 Keystone Server 驗證的 URI (/v2.0/tokens) 發送 POST 驗證請求,並以 JSON 格式傳送 相關參數與 Header:
- Body: {
"auth": {
"passwordCredentials": {
"username": "系統帳號",
"password": "系統密碼"
}}}
- Header: Content-Type = "application/json"
(2). 外部驗證機制(External Authentication)
系統的帳號驗證模組接收到使用者合法之各雲端或本地端帳號與密碼,
藉由帳號對應關係,取得使用者於系統內部的身分識別(系統帳號),向 Keystone Server 驗證的 URI (/v3/auth/tokens) 發送 POST 驗證請求,並以 JSON 格式傳送相關參數與 Header:
- Body: {"auth":{"identity":{"methods":["external"],"external":{}}}}
- Header: REMOTE-USER = "系統帳號"
- Header: Content-Type = "application/json"
最後當通過 Keystone 帳號密碼驗證或外部驗證時,Keystone 將以 JSON 格 式返回相關資訊,包含 Token 核發日期與有效日期、Token_id 等,而系統將以 Keystone Token 作為系統頒發給通過驗證使用者的 Token。
( 2 ). 手機驗證之實作
由於系統整合 Twilio 公司所提供的 SMS 簡訊服務,因此必須先於 Twilio 官 方網站註冊取得 credentials(account_sid 與 auth_token),並透過 credentials 來存取 Send Message API 使用 SMS 簡訊服務。在實作上,手機驗證碼以隨機五位數的 整 數 亂 數 來 產 生 , 並 設 定 五 分 鐘 時 效 性 , 接 著 再 透 過 twilio.rest 模 組 的 TwilioRestClient、MessageCreate 函式來建立訊息並傳送到使用者手機。使用者 收到簡訊後,於系統手機驗證頁面輸入簡訊內容中的驗證碼來完成手機驗證。
以虛擬碼(pseudo code)描述如下: (圖四十三)
圖 四十三:手機驗證實作之虛擬碼
( 3 ). 各雲端單一登入之實作
使用者可以選擇欲單一登入多個公有雲及私有雲,系統則根據該雲端帳號認 領與否,而有不同之公、私有雲驗證流程。若使用者選擇登入已認領之雲端,則 表示系統於帳號對應表中已記錄該雲端之使用者帳號與密碼,而系統透過啟用多 個執行緒來分別完成各雲端之驗證。若使用者選擇登入未認領之雲端,則系統將 直接把使用者導向公、私有雲驗證頁面進行登入。在通過各雲端驗證後,系統取 得各雲端 Token 並記錄於該使用者之帳號對應表中。
以虛擬碼(pseudo code)描述如下: (圖四十四)
圖 四十四:各雲端單一登入實作之虛擬碼
針對虛擬碼中,系統在公有雲帳號驗證與私有雲帳號驗證之實作細節描述如 下:
( 3.1 ) 公有雲 OpenID 帳號驗證之實作
首先必須於各雲端身分提供商(簡稱為雲端商)之開發人員網站申請 OAuth 2.0 credentials,包含: 一組 client ID 與 client secret,並設定 redirect URI 告知雲
端商驗證請求的返回位置。系統透過此 credentials 來介接雲端商提供的 OpenID Connect 驗證 API,對使用者進行驗證並取得其他雲端服務 API 的存取權杖 (Token)。
其中 OpenID Connect 驗證之實作步驟如下:
a. 建立 cross-site request forgery (CSRF) tokens
以 hashlib 模組的 md5 雜湊函式,對 30 位元的隨機亂數進行雜湊運算 產生 CSRF tokens,並儲存於 session 中以便後續雲端商返回驗證請求時,利 用此 session 進行核對(verify),以預防跨網站的偽造請求攻擊(cross-site request forgery attacks)。
b. 向雲端身分提供商請求驗證
以 HTTPS GET 向各自雲端商之驗證端點請求OpenID Connect驗證如下 (表八),且於 URI 攜帶相關參數內容如下(表九):
表 八:OpenID Connect 提供商之驗證端點表 Provider Endpoint
Google https://accounts.google.com/o/oauth2/auth Facebook https://graph.facebook.com/oauth/authorize Dropbox https://www.dropbox.com/1/oauth2/authorize Amazon https://www.amazon.com/ap/oa
Microsoft https://login.live.com/oauth20_authorize.srf 表 九:OpenID Connect 驗證 URI 參數列表
參數名稱 描述
client_id 在各雲端商之開發人員網站,所申請的
OAuth 2.0 credentials(client ID 與 client secret)。
redirect_uri 在各雲端商之開發人員網站,所設定的
redirect URI。
scope 資源請求的宣告。
(此參數值可於維護管理系統之公有雲 相關資源請求頁面進行設定)
response_type 系統預設值等於"code",表示遵循 OpenID Connect 之 Authorization Code Flow。
access_type 系統預設值等於"offline",表示請求取得 永久有效的存取權杖(refresh token)。
假 設 最 後 準 備 完 成 之 OpenID Connect 驗 證 URI 為 https://provider_endpoint?client_id=clientID&redirect_uri=redirectURI&scope
=scope&response_type=code&access_type=offline,系統將根據使用者該公有 雲帳號認領與否,而採取以下不同方式向雲端商提出此驗證請求:
(a). 轉址導向雲端商驗證網頁
若 該 公 有 雲 帳 號 未 認 領 , 則 系 統 透 過 django.http 模 組 的 HttpResponseRedirect 函式,直接將使用者導向該驗證 URI,於雲端商 驗證頁面進行登入,且由使用者同意授予資源存取權給本系統。
(b). 網頁自動化
若該公有雲帳號已認領,則系統藉由 pyvirtualdisplay 與 selenium 套 件分別啟動 Virtual Display 與 FireFox 瀏覽器,在兩者的配合之下於伺 服器端產生 Headless FireFox web browser,接著以 python 語言呼叫 selenium 所提供的 FireFox WebDriver API 來控制 Headless browser 的行 為如下(表十一),並模擬使用者於公有雲驗證頁面進行登入,以及公有 雲資源授權同意的行為。
表 十:Selenium FireFox WebDriver API 列表
FireFox API 功能描述
find_element_by_id("html_id_attribute") 於雲端商驗證頁面以 id attribute 搜尋帳號、密碼的 輸入欄位、登入鈕、
OAuth2.0 資源授權同意 鈕。
send_keys("value") 於對應欄位填入帳號、密碼 值。
click() 點擊登入鈕或資源授權同
意鈕。
c. 核對 CSRF tokens
完成驗證後,雲端商將返回 HTTPS response 至 redirect URI,而系統比 對網址列資訊(Query String)中的 state 參數值是否與 session 所記錄的 CSRF tokens(步驟 1)相同,以預防跨網站的偽造請求攻擊。
d. 請求取得雲端服務存取權杖(token)
以 HTTPS POST 向各自雲端商之 token 端點請求取得 Access Token 與 Refresh Token 如下(表十一),且於 POST body 以 JSON 格式攜帶相關參數內 容如下(表十二):
表 十一:OpenID Connect 提供商之 Token 端點表 提供者 Token Endpoint
Google https://accounts.google.com/o/oauth2/token Facebook https://graph.facebook.com/oauth/access_token Dropbox https://api.dropbox.com/1/oauth2/token
Amazon https://api.amazon.com/auth/o2/token
表 十二:OpenID Connect Token URI 參數列表 參數名稱 描述
code 即 Authorization Code,可於步驟 3 網址列資訊(Query String)中的 code 參數值取得。
client_id 在各雲端商之開發人員網站,所申請的 OAuth 2.0 credentials(client ID 與 client secret)。
client_secret 同上。
redirect_uri 在各雲端商之開發人員網站,所設定的 redirect URI。
grant_type 系統預設值等於"authorization_code"
Token 請求成功後,雲端商以 JSON 格式返回相關資訊,包含 Access Token、Refresh Token、使用者雲端帳號等資訊。而系統將根據使用者之系 統帳號與雲端帳號,於帳號對應表找到對應紀錄來儲存 Token 資訊。
( 3.2 ) Hadoop Kerberos 帳號驗證之實作
系統以支援 Kerberos 驗證的 Hadoop 私有雲為例,透過 Kerberos 驗證取得能 夠存取 Hadoop 上相關服務(如: Hadoop Distributed File System ; HDFS)的 Ticket。
在實作上,首先透過 subprocess 套件的 Popen 函式,啟動一個子程序執行 kinit 命令,並以使用者 Kerberos 帳號(principal)與密碼登入 KDC (Key Distribution Centers)取得 TGT(Ticket Granting Ticket)。接著再依序透過 kerberos 套件的 authGSSClientInit、authGSSClientStep、authGSSClientResponse 函式,以 TGT 換 得 能 夠 存 取 Hadoop HDFS 服 務 的 SGT(Service Granting Ticket) , 其 中 authGSSClientInit 函式所需帶的參數為在 Kerberos 中 Hadoop 相關服務之 Service principal 名稱,本系統以 Hadoop HDFS Service principal 為例。而系統將根據使 用者之系統帳號與 Hadoop Kerberos 帳號,於帳號對應表找到對應紀錄來儲存 Ticket 資訊。
Microsoft https://login.live.com/oauth20_token.srf
( 3.3 ) OpenStack Keystone 帳號驗證之實作
系統藉由 OpenStack 中的 Keystone 驗證元件,其對外提供的驗證介面(Identity API v2.0)來完成登入驗證並取得能夠存取 OpenStack 上相關服務(如: OpenStack Swift)的 Token。
在實作上分為以下步驟:
(a). 向 OpenStack Identity Service (Keystone)請求驗證
系統向 OpenStack Keystone 驗證 URI(/v2.0/tokens) 發送 POST 驗證請求,
並以 JSON 格式傳送相關參數與 Header:
- Body: {
"auth": {
"passwordCredentials": {
"passwordCredentials": {