1335 字
7 分鐘
#7 自建Azure AD驗證機制 — 簡單入門Azure AD
2023-04-03
無標籤

老實說,這篇內容並不簡單,我也研究好幾個月,當初的需求是,希望能取代Azure AD原本的驗證機制,自建另外一套驗證,就能在上面進行更多操作。本篇將說明如何自建SAML伺服器,取代原本Azure AD驗證。


SAML#

下面會需要了解的SAML的驗證機制,先說明一下。

SAML(Security Assertion Markup Language)是一種用於在不同安全環境下進行身份驗證和授權的標準協議。在SAML中,有兩個主要的角色:身份提供者(Identity Provider,IdP)和服務提供者(Service Provider,SP)。

IdP是一個系統或服務,負責驗證和管理使用者的身份資訊。並通過使用者提供的帳號、密碼進行身份驗證,並生成一個包含使用者身份資訊的SAML 斷言,斷言會被傳送給SP。

SP是指需要介接身分驗證的系統,SP在與IdP建立信任關係後,可以接收和解析SAML斷言,以驗證使用者身份。


介接原理#

基本上網頁服務若要在Azure AD進行帳號驗證,都會使用SSO,SSO又分為OAuth、SAML兩種方式提供開發者串接。

微軟允許管理員設定當我們進入SSO後,可以跳轉到第三方的SAML IdP伺服器進行驗證,此時Azure AD SSO則扮演SAML SP的角色,驗證完成後再跳轉回Azure AD SSO,來完成登入的動作。

設定跳轉到SAML IdP,是將網域所有使用者進行跳轉,沒辦法在同個網域中,部分人使用SAML驗證,部分人使用微軟原本的驗證機制。

要完成以上介接需要解決Azure AD與SAML的串聯,並開發自己的SAML IdP伺服器。介接資訊可以參考微軟文件


Demo#

先展示一下效果,會比較好理解。我已經將twcanhelp.me這個網域設定SAML驗證。

按下登入後,會顯示 正在將您導向您組織的登入頁面。

接下來會跳轉到我撰寫的頁面,我這裡設計是只要按下登入,不用密碼就會登入,之後就會跳回去微軟頁面完成登入。


開設測試帳號#

上面的範例不管登入Email填誰,最後都會登入同一個帳號,我們需要先建立這一個測試帳號。建議不要在Azure Portal建立帳號,因為會缺少一些參數。

隨便找一台電腦執行Powershell,並輸入以下語法建立使用者:

Connect-MsolService # 登入
New-MsolUser -UserPrincipalName "test@twcanhelp.me" `
  -DisplayName "test" -ImmutableId "Meow"

ImmutableId(內部部署固定 ID)這個使用者欄位相當於身份證字號,作為使用者的唯一識別,Azure AD SSO與SAML Idp溝通就是透過該欄位,然後在Azure Portal預設建立使用者並不會產生ImmutableId,會是一個空白,就會導致使用者無法透過SAML驗證,因此我建議透過指令新增測試帳號。

如果是從AD透過Azure AD Connect同步上來的帳號預設都會有ImmutableId,就不需要手動設定。


開發SAML IdP伺服器#

我們需要先架設好自己的SAML IdP伺服器,才能夠跟Azure AD介接,我開發了Laravel的範例可以參考。我的範例PHP主要是用lightsaml來實作,其他語言要架設IdP可以參考這篇文章

首先,SAML伺服器會有一組憑證作驗證,需要自己產,透過以下指令產生公鑰與私鑰。

Terminal window
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout key.pem -out cert.pem -days 3650

接下來我們設定參數到 .env檔,參數如下

  • SAML_KEY_BASE64 : 上面產生key.pem的base64
  • SAML_CERT_BASE64 : 上面產生cert.pem的base64
  • SAML_ISSUER : 發行人,我建議填網址,如https://saml.twcanhelp.me/
  • SAML_NAME_ID : 填上面測試帳號的ImmutableID

再來將服務跑起來,並綁到網域saml.twcanhelp.me。

docker-compose up -d php

設定介接Azure AD#

接下來需要設定Azure AD的設定,告訴他要跳轉到哪裡進行驗證。主要步驟都是參考這篇文章

隨便找一台電腦執行powershell,並設定參數,參數說明如下:

  • DomainName : 帳號的網域
  • FederationBrandName : 隨便自訂名稱
  • Authentication : 設定Federated,代表使用同盟進行驗證
  • SigningCertificate : 剛剛上面自簽的公鑰,把頭尾標籤拿掉,中間換行字元拿掉組成一行字。
  • PassiveLogOnUri : 登入的網址
  • LogOffUri : 登出的網址,這邊我用不到登出,就隨便寫個
  • IssuerUri : 發行人識別,需要跟上面SAML_ISSUER一樣
Connect-MsolService # 登入
$dom = "twcanhelp.me"
$BrandName = "SAML 2.0 IDP"
$LogOnUrl = "https://saml.twcanhelp.me/login"
$LogOffUrl = "https://saml.twcanhelp.me/"
$MyURI = "https://saml.twcanhelp.me/"
$MySigningCert = "XXXXXXXXXX"
$Protocol = "SAMLP"
Set-MsolDomainAuthentication `
-DomainName $dom `
-FederationBrandName $BrandName `
-Authentication Federated `
-PassiveLogOnUri $LogOnUrl `
-SigningCertificate $MySigningCert `
-IssuerUri $MyURI `
-LogOffUri $LogOffUrl `
-PreferredAuthenticationProtocol $Protocol

執行成功後,到Azure Portal後台,會發現網域的同盟被打勾,這樣就完成了。同盟後,就無法再Azure Portal頁面新增使用者,需要透過指令。

若是要解除跳到第三方驗證,則要下指令

Terminal window
Set-MsolDomainAuthentication -DomainName $domain -Authentication Managed

要取得目前設定的資訊可以下

Get-MsolDomainFederationSettings

結語#

透過自建SAML伺服器就能整合原本的Azure AD驗證機制,而且由於是先經過Azure AD再跳轉到SAML驗證,並不會影響到原本已經跟Azure AD SSO介接的系統。