縱有倚天劍還要屠龍刀,實現Power BI報表服務器自定義認證
概述
在Power BI報表服務器身份認證體系上,我們默認使用AD作爲認證體系,AD即活動目錄體系來說,是微軟整個平臺的核心,可以說是倚天劍。默認情況下, Power BI 報表服務器 接受指定 Negotiate 或 NTLM 身份驗證的請求。 如果部署中包括使用這些安全提供程序的客戶端應用程序和瀏覽器,則可以使用這些默認值,而無需附加配置。 如果要使用不同的安全提供程序來獲取 Windows 集成安全性(例如,如果要直接使用 Kerberos)或者修改了默認值並且要還原原始設置。
但是很多用戶不使用AD作爲驗證,希望用自己的認證程序來進行驗證,比如使用數據庫用戶名和密碼進行驗證。 Power BI 報表服務器也支持自定義安全認證,這是一把屠龍刀,實現你對驗證的無限需求 。
Power BI 報表服務器提供了可擴展的體系結構,該體系結構允許您插入自定義的或基於窗體的身份驗證模塊。 如果部署要求不包含 Windows 集成安全性或基本身份驗證,則可考慮實現自定義的身份驗證擴展插件。 使用自定義身份驗證的最常見情形是支持對 Web 應用程序的 Internet 或 Extranet 訪問。 使用自定義身份驗證擴展插件替換默認的 Windows 身份驗證擴展插件,可更好地控制如何授予外部用戶訪問報表服務器的權限。
利用 Power BI 報表服務器 安全擴展插件,可以對用戶或組進行身份驗證和授權;這樣,不同的用戶便可登錄至同一臺報表服務器,並基於他們的標識執行不同的任務或操作。 默認情況下,Power BI 報表服務器 使用基於 Windows 的身份驗證擴展插件,該插件使用 Windows 帳戶協議來驗證聲明在系統上擁有帳戶的用戶的標識。 Power BI 報表服務器 使用基於角色的安全系統爲用戶授權。 Power BI 報表服務器 基於角色的安全模型與其他技術的基於角色的安全模型類似。
因爲安全擴展插件基於可擴展的開放式 API,所以您可以在 Power BI 報表服務器 中創建新的身份驗證和授權擴展插件。 下面的示例爲使用基於窗體的身份驗證和授權的典型安全擴展插件實現:
如圖所示,身份驗證和授權將按以下所示發生:
- 用戶嘗試使用 URL 訪問 Web 門戶,然後被重定向至爲客戶端應用程序收集用戶憑據的窗體。
- 用戶向該窗體提交憑據。
- 用戶憑據通過 LogonUser 方法提交至 Reporting Services Web 服務。
- Web 服務調用客戶提供的安全擴展插件,並驗證相應的用戶名稱和密碼是否存在於自定義安全機構中。
- 進行身份驗證之後,Web 服務創建一個身份驗證票證(稱爲“cookie”),管理票證,然後爲 Web 門戶的主頁驗證用戶角色。
- Web 服務將此 cookie 返回至瀏覽器,然後在 Web 門戶中顯示相應的用戶界面。
- 對用戶進行身份驗證之後,在 HTTP 標頭中傳送此 cookie 的同時瀏覽器向 Web 門戶發出請求。 這些請求用於響應 Web 門戶中的用戶操作。
- 此 cookie 在 HTTP 標頭中與請求的用戶操作一起傳送至 Web 服務。
- 對此 cookie 進行驗證,如果有效,則報表服務器從報表服務器數據庫中返回安全描述符及與請求的操作有關的其他信息。
- 如果此 cookie 有效,報表服務器將調用安全擴展插件檢查用戶是否有權執行特定操作。
- 如果用戶已有相應權限,則報表服務器將執行請求的操作,並將控制權返回調用方。
- 用戶經過身份驗證後,報表服務器進行 URL 訪問都會使用此 cookie。 此 cookie 在 HTTP 標頭中傳送。
- 用戶繼續請求對報表服務器的操作,直到會話結束爲止。
如何實現
Power BI 報表服務器 引入了一個新的 Web 門戶以託管新的 Odata API,並也託管新的報表工作負載,例如移動報表和 KPI。 此新門戶依賴於更新的技術,並通過在單獨的進程中運行與熟悉的 ReportingServicesService 分隔開來。 此進程不是 ASP.NET 託管的應用程序,因此中斷了現有自定義安全擴展插件中的假設。 此外,自定義安全擴展插件的當前接口不允許傳入任何外部上下文,留給實現者唯一的選擇來檢查熟知的全局 ASP.NET 對象,這要求對接口進行一些更改。
引入了可實現的一個新接口,此接口提供一個 IRSRequestContext,提供擴展插件用於做出與身份驗證相關決定的更常見屬性。
在以前的版本中,報表管理器位於前端,並且可以使用其自定義登錄頁面進行配置。 在 Reporting Services 2016 中,僅支持 reportserver 託管的一個頁面,並且應對兩個應用程序都進行身份驗證。
大多數泛型示例訪問 HttpContext.Current 來讀取如標頭和 Cookie 等請求的信息。 爲了使擴展插件能夠做出相同的決策,我們在提供請求信息的擴展中引入了一個新方法,並在從門戶進行身份驗證時調用該方法。
擴展插件必須實現 IAuthenticationExtension2 接口才能利用此方法。 擴展插件需要實現 GetUserInfo 方法的兩個版本,正如 reportserver 上下文所調用的方法,以及其他在 webhost 進程中所使用的方法。 以下示例展示了此門戶的一個簡單實現,其中使用了 reportserver 解析的標識。
public void GetUserInfo(IRSRequestContext requestContext, out IIdentity userIdentity, out IntPtr userId)
{
userIdentity = null;
if (requestContext.User != null)
{
userIdentity = requestContext.User;
}
// initialize a pointer to the current user id to zero
userId = IntPtr.Zero;
}
配置部署和Demo
需要實現自定義擴展認證,需要有幾個步驟。在github上有一個demo https://github.com/Microsoft/Reporting-Services/tree/master/CustomSecuritySample
如果你安裝demo的步驟,數據庫和Power BI 服務器在一個服務器上,那麼基本上很簡單就搞定,我在進行測試中遇到了幾個問題,給大家分享下。
1、先下載此Demo 打開後,可以進行編譯,如果不能通過,可能需要添加 Microsoft.ReportingServices.Interfaces 這可以在 C:\Program Files\Microsoft Power BI Report Server\PBIRS\PowerBI 目錄下找到 Microsoft.ReportingServices.Interfaces.DLL進行引用
2、對於需要對身份驗證 Cookie 進行解密的窗體身份驗證,需要使用相同的計算機密鑰和解密算法對這兩個進程進行配置。 所以我們需要生成一個強密鑰和使用一些工具來生成密鑰,例如 Internet Information Services 管理器 (IIS)。 在 Internet 上可以找到其他工具。
首先,使用 Visual Studio 開發人員命令提示符 來進行創建密鑰
打開後,跳轉到需要的目錄,如cd c:\test ,然後輸入: sn -k SampleKey.snk
生成的samplekey.snk需要和程序關聯,點擊應用程序的屬性,選擇簽名,選擇強簽名密鑰文件爲剛生成的samplekey.snk
3、生成密鑰,生成密鑰理論有很多方法實現,我的這臺服務器安裝了IIS 我使用IIS進行生成密鑰,打開IIS 選擇計算機密鑰。
點擊後選擇 驗證方法AES,加密方法AES。生成的密鑰記錄下來備用。
4、編譯項目。生成相應的文件。部署項目:
- Copy the Logon.aspx 部署到 C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer 目錄
- Copy Microsoft.Samples.ReportingServices.CustomSecurity.dll and Microsoft.Samples.ReportingServices.CustomSecurity.pdb to the C:\Program Files\Microsoft Power BI Report Server\PBIRS\ \ReportServer\bin 目錄
- Copy Microsoft.Samples.ReportingServices.CustomSecurity.dll and Microsoft.Samples.ReportingServices.CustomSecurity.pdb to the C:\Program Files\Microsoft Power BI Report Server\PBIRS\ \Portal` 目錄.
- Copy Microsoft.Samples.ReportingServices.CustomSecurity.dll and Microsoft.Samples.ReportingServices.CustomSecurity.pdb to the C:\Program Files\Microsoft Power BI Report Server\PBIRS\ \PowerBI` 目錄.
5、修改 C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer\ RSReportServer.config
-
在
<AuthenticationTypes>
節下修改爲<Authentication> <AuthenticationTypes> <Custom/> </AuthenticationTypes> <RSWindowsExtendedProtectionLevel>Off</RSWindowsExtendedProtectionLevel> <RSWindowsExtendedProtectionScenario>Proxy</RSWindowsExtendedProtectionScenario> <EnableAuthPersistence>true</EnableAuthPersistence> </Authentication>
在元素中找到<Security>``<Authentication>``<Extensions>
修改如下: 這裏的username是管理員的名稱,比如我這裏設置爲maxbiuser
<Security>
<Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.Authorization, Microsoft.Samples.ReportingServices.CustomSecurity" >
<Configuration>
<AdminConfiguration>
<UserName>maxbiuser</UserName>
</AdminConfiguration>
</Configuration>
</Extension>
</Security>
<Authentication>
<Extension Name="Forms" Type="Microsoft.Samples.ReportingServices.CustomSecurity.AuthenticationExtension,Microsoft.Samples.ReportingServices.CustomSecurity" />
</Authentication>
下面加入:
<MachineKey ValidationKey="[YOUR KEY]" DecryptionKey="[YOUR KEY]" Validation="AES" Decryption="AES" />
下加入,配置直通 cookie
<UI>
<CustomAuthenticationUI>
<PassThroughCookies>
<PassThroughCookie>sqlAuthCookie</PassThroughCookie>
</PassThroughCookies>
</CustomAuthenticationUI>
</UI>
6、修改 rssrvpolicy. config 文件
-
需要爲自定義安全擴展添加一個代碼組, 該代碼組將授予您的擴展的 fulltrust 權限。爲此, 可以將代碼組添加到 rssrvpoligy. config 文件中。
-
打開位於目錄中的 rssrvpolicy. config 文件。 C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer`
-
在安全策略文件中的現有代碼組之後添加以下元素, 如下所示, 然後添加一個條目, 如下所示, 以 rssrvpolicy. config。請確保根據您的 reportserver 安裝目錄更改以下路徑:
<CodeGroup>
<CodeGroup class="UnionCodeGroup" version="1" Name="SecurityExtensionCodeGroup" Description="Code group for the sample security extension" PermissionSetName="FullTrust"> <IMembershipCondition class="UrlMembershipCondition" version="1" Url="C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer\bin\Microsoft.Samples.ReportingServices.CustomSecurity.dll"/> </CodeGroup>
7、修改報表服務器的 web. config 文件
在文本編輯器中打開 web. config 文件。默認情況下, 該文件位於目錄中。 C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer`
-
找到該元素, 並將 “模擬” 屬性設置爲 false。
<identity>
<identity impersonate="false" />
-
找到該元素, 並將 mode 屬性更改爲窗體。此外, 將以下元素添加爲元素的子元素, 並設置 loginurl、名稱、超時和路徑屬性, 如下所示:
<authentication>``<forms>``<authentication>
<authentication mode="Forms"> <forms loginUrl="logon.aspx" name="sqlAuthCookie" timeout="60" path="/"></forms> </authentication>
-
直接在元素之後添加以下元素。
<authorization>``<authentication>
<authorization> <deny users="?" /> </authorization>
這將拒絕未經身份驗證的用戶訪問報表服務器的權限。該元素以前建立的 loginurl 屬性將未經身份驗證的請求重定向到 logon. aspx 頁。
8、使用CustomSecuritySample\Setup下面 CreateUserStore.sql 創建用戶表
排錯
部署完成後,重啓Power BI 服務器服務。訪問我的報表地址是81端口:http://maxtestweb:81/Reports
會跳轉到 http://maxtestweb:81/ReportServer/logon.aspx?ReturnUrl=/ReportServer/localredirect?url=%2freports
但是我在訪問的時候報錯,出現500錯誤什麼的,檢查完成一遍後,還是報錯。 檢查日誌發現:
runtimeBroker沒有權限。 打開註冊表,找到appid,然後右鍵權限,將所有者改爲管理員。
然後使用組件服務,找到 runtimeBroker,點擊屬性 權限添加相應的用戶權限。
重啓服務器,然後刷新,看到登錄界面。終於看到了希望。點擊註冊用戶,報告無法鏈接到數據庫服務器。
代碼裏面AuthenticationUtilities.cs可以看到:
sqlconnection使用的參數是:Properties.Settings.Default.Database_ConnectionString 這詭異的地方。這裏自己改到仔細的數據庫服務器。
改完後登錄後的效果。
總結
以上方法實現了自定義認證,因爲可以自定義了既可以實現各種驗證方法,比如多因子。過程看起來比較繁瑣,還是比較容易實現的。AuthenticationUtilities.cs和login.cs可以實現更多的內容。
有問題大家一起談談
作者簡介: Max Shen(阿特),爲了成爲數據專家而努力,萬一實現了呢!有多年的系統運維,數據庫運維經驗。近20年的IT從業經驗,在微軟有超過10年的工作經驗。對數據庫運維調優,排錯,有獨到能力。電話微信18628037379,[email protected]