【转载请注明出处】
本文目标人群是对Power BI本地部署和第三方系统集成以及如何做数据权限控制有疑问的童鞋。Power BI本地部署的正确全称是Power BI Report Server,下载地址短域名http://aka.ms/pbireportserver,简称PBI RS。
先说结论,PBI RS可以在不同的环境下实现和第三方系统的集成和并且可以针对不同用户做到数据权限控制。
开始之前先说明一下认证和授权这两个概念。认证,是PBI RS识别请求访问的用户是不是有效用户。授权,是用户在经过PBI RS认证是有效用户之后,PBI RS来解决这个用户有没有权限访问某个页面的功能。在下文的讨论中,主要讨论不同的认证方式,然后会讨论授权中关于数据授权的部分。
PBI RS的核心框架和SQL Server的Reporting Service非常相似(其实两者从实现机制上差别巨大,这里不做深究),可以简单的理解为,PBI RS是一个.Net Web Site,如果要实现和它的深度集成,把它作为一个.Net Web Site来集成就可以了。第三方系统和它做集成有两种方式:AD认证的集成模式、Form认证的集成模式。这两种方式没有优劣之分,只有合适与否。
AD认证的集成模式
AD(或者Windows)认证是PBI的默认认证方式。在这种方式下,需要第三方应用也采用了AD的认证方式才可以正常的和PBI RS做集成。注意,这种方式要求第三方系统采用了AD的认证方式,并且用户在使用AD账户登录了操作系统,才能正常的不用输入登录用户名和密码去访问PBI RS或第三方系统。不用登陆的原因是用户在登陆操作系统时,已经输入了用户名和密码经过了AD的认证。这里不做第三方系统和AD集成的探讨,如果有需求,请参考微软官方的文档。
在第三方系统做好了AD的集成后,与PBI RS的集成,官方给出了通过URL的方式在第三方做iframe的嵌入。即通过将报表的地址,然后增加后缀 ?rs:embed=true的方式来实现集成。如果在浏览器直接输入,其对比效果如下:
访问/reports/powerbi/test/RLS?rs:embed=true的效果,只有报表区域。
访问/reports/powerbi/test/RLS的效果,包含了PBI RS的一些固有元素。
如果你还想在URL里传入参数,控制PBI报表的显示内容,还可以通过这样的参数组合来实现:reports/powerbi/[report_path]?rs:Embed=true&filter=[table_name]/[column_name or measure_name] eq 'value' [and [table_name]/[column_name or measure_name] eq 'value']
【对自定义制作报表场景有硬需求的用户一定要注意这段】
在AD认证模式下,用户使用PBI Desktop(本地版本)编辑完报表后,可以直接另存到PBI RS上。因为运行PBI Desktop的账户是AD账户,因此PBI Desktop和PBI RS之间是有认证关系的。那如果用户在非域的windows上访问系统并且编辑报表,然后也想将报表直接另存到PBI RS上怎么办?一个解决方案是,使用runas命令(runas /netonly /user:username "exefilepath")。有需求的童鞋可以查一下这个命令的用法,然后给这类用户一个bat批处理文件(或其他形式的可以使用runas命令或类似命令的交付物),用bat文件来代替原来的pbi desktop的启用方式。
此外,如果对安全性要求不是很高,用户也可以通过js里的xmlhttprequet对象,使用get方法将用户名和密码传递给PBI RS然后再请求iframe中的报表地址。这种方式需要注意两点,第一是用户名和密码实际是明文get请求到PBI RS的;第二需要考虑不同浏览器对脚本的支持情况。
很多时候,用户的环境不是纯AD的环境,或者使用了其他的SSO方案,这时候怎么做呢?我们可以使用PBI RS的Form认证方式。
在AD认证中的权限控制
PBI RS中如果想实现不同用户访问同一张报表时,看到的数据只能是这个用户权限范围之内的数据,则需要通过结合SSAS(SQL Server Analysis Service)来实现。具体步骤如下:
在AD中创建user1和user2。
使用SSDT(SQL Server Data Tools,请通过搜索引擎从微软官网下载),创建一个SSAS的tabular模型,然后部署到SSAS中。具体操作步骤,请参考官方教程:https://docs.microsoft.com/zh-cn/sql/analysis-services/tutorial-tabular-1400/as-adventure-works-tutorial?view=sql-analysis-services-2017,教程内容比较丰富,如果仅需要快速了解权限相关,请直接跳转到教程列表的“补充课程-动态安全性”部分。这个步骤的重点是,在模型中额外创建user1和user2对应的数据权限映射表,然后在这个权限映射表中,使用USERNAME()函数来做过滤。
使用PBI Desktop直连(Direct Query而非Import)到SSAS中对应的模型,制作报表,然后将报表发布到PBIRS。
user1和user2在PBI RS中都被管理员授予报表的浏览权限。
使用user1和user2在访问这张报表时,数据会按不同的用户做对应的呈现。
有些时候,用户可能会遇到下面的错误:
一般这种情况是由于服务器采用了k8s认证模式,而服务器却没有做好对应的配置,遇到这种情况,请参考: https://docs.microsoft.com/zh-cn/power-bi/report-server/configure-kerberos-powerbi-reports
Form认证的集成模式
PBI RS本身是一个.Net Web应用,实现其Form认证和.Net Web程序的Form认证基本原理一样。PBI RS提供了接口让用户可以实现自定义的Form认证。所谓的自定义就是,你可以选择实现你希望的PBI RS认证逻辑,是通过账号密码,还是SSO服务器的某种标准(比如SAML),只要用户在PBIRS的扩展模块实现了IAuthenticationExtension2接口。微软给出了示例代码,并放到了github上。示例代码下载地址:https://github.com/Microsoft/Reporting-Services/tree/master/CustomSecuritySample。完成Form认证的设置需要的步骤比较多,而且需要比较多的.net web相关知识,为了让大家可以更快上手,微软在github上的示例代码的最近更新中,添加了一个powershell脚本,可以实现一键部署,方便了大家体验Form认证。
在Form认证模式下,第三方系统可以非常方便的和PBI RS做集成。比较推荐的方式还是使用官方介绍的embed的URL方式。但是在Form认证下,目前存在一个问题是,PBI Destkop在制作完报表后,无法直接另存到PBI RS中。用户尝试在另存为的时候 ,会得到服务器返回的一个错误。目前这个错误是由于PBI Desktop在当前版本还不支持Form认证,根据PBI社区的信息,产品组已经在制作相关的功能,下个版本可能会解决。目前的一个解决办法是,用户编辑完pbix报表后,不要另存为,而是选择先存到本地,然后再登陆到PBI RS,利用上传功能,将pbix文件上传到PBI RS上。这种模式下,为了安全性考虑,上传的pbix的数据源连接的信息会丢失(如果不丢失就需要PBIRS保存用户指定的数据源的用户名和密码,这点会有比较大的安全隐患),需要用户在PBI RS站点上再编辑一下上传的pbi报表的数据源信息,pbi报表才可以正常显示。而每次上传报表后还要再次做一次数据源的编辑对用户来说,操作过于繁琐。因此,我们可以做一个简单的页面,这个页面使用PBI RS提供的RESTAPI来实现pbix文件的上传,在上传完毕后,调用相关RESTAPI,将这个报表的数据源信息自动重写。关于RESTAPI的功能,不在这里详述了,有兴趣的童鞋可以去PBI官网的文档中查看更多信息。
在Form认证中的权限控制
在Form认证中,PBI RS的用户不再是AD用户,而SSAS不支持非AD用户(或windows用户)之外的认证方式。这种情况下怎么控制不同用户的数据权限呢?答案是,还是通过SSAS来完成。具体思路如下:
在PBI RS里创建user1和user2
使用SSDT创建SSAS模型,然后发布到SSAS,注意,在创建模型时,依然需要一张用户和数据权限的映射表。此时暂时先不处理权限的映射。
使用PBI Desktop通过直连的方式直连到SSAS,然后创建报表,并将pbix文件上传到PBI RS上。
在PBI RS上编辑这张报表的数据源成以下格式:
Data Source=[server name or server ip];Initial Catalog=[model name];customdata={}
注意,红色部分是核心。customdata是SSAS的连接字符串的扩展参数;{}是PBI RS的内置通配符,会将这个通配符的值替换成当前PBI RS登陆用户,然后传递给SSAS。
在SSAS中,增加一个角色,在这个角色的数据过滤条件中,输入类似于下面的格式的公式:
=Mapping_table[username]=CUSTOMDATA()
使用user1和user2登陆报表,查看到这张报表的数据已经根据用户做了过滤。
一些常见问题:
PBI RS的REST API怎么调用?
简单来说,需要访问/reports/api/v2.0/me,获得PBI RS的cookie,然后使用这个cookie去访问其他的api。
我想禁止用户下载PBI里的数据,怎么做?
使用SQL Server Management Studio连接到PBI RS服务,然后将服务器属性EnablePowerBIReportExportData的值改成False。
PBI RS只有很少的几个角色,怎么创建新的具有自定义权限的角色?
使用SQL Server Management Studio连接到PBI RS后,在服务器的角色中创建新的角色。
如何通过Management Studio管理PBI RS?
打开SSMS,使用Reporting service类型,连接地址为 http://servername/reportserver。
本文参考的一些连接:
https://blogs.msdn.microsoft.com/dataaccesstechnologies/2017/09/15/sql-server-reporting-services-2016-integration-with-an-application/
https://blogs.msdn.microsoft.com/sqlrsteamblog/2016/06/03/passing-user-names-to-analysis-services-with-personalized-connection-strings-in-sql-server-2016-reporting-services/
https://www.kasperonbi.com/using-customdata-and-ssas-with-power-bi-embedded/
欢迎关注个人公众号,不定期发布一些数据分析的技术内容。
领取专属 10元无门槛券
私享最新 技术干货