嗯……真正能够通过 ADOMD.Net 完成它是一段相当长的旅程。
核心方法:核心理念是与 SSAS 服务器的连接仅支持基于 Windows 集成安全的身份验证。sa
SSAS 不支持我们在 SQL Server 中为用户执行的 SQL 身份验证。
因此,基本想法是尝试使用基于 Windows 集成安全的身份验证连接到 SSAS 服务器,并在我们尝试检查的用户的上下文中触发 MDX 查询。如果查询成功执行,则用户有权访问。如果查询执行返回错误/异常,则用户无权访问。
请注意,由于此处描述的原因,仅仅能够打开到 SSAS 服务器的连接并不是用户访问的指标。您必须触发查询以检查访问权限。
对于 ADOMD.Net,直到 v12.x:
现在,我们知道基于 Windows 集成安全性的身份验证总是从应用程序/进程正在运行的用户上下文中获取用户详细信息。您不能在 ADOMD.Net 连接的连接字符串中传递用户凭据。这是我为完成它而编写的代码。您需要Microsoft.AnalysisServices.AdomdClient.dll
在您的 C# 项目中引用。
using Microsoft.AnalysisServices.AdomdClient;
public static int IsSsasAccessibleToUser(string ssasServerName)
{
var hasAccess = 0;
try
{
using (var adomdConnection = new AdomdConnection($"provider=olap;datasource={ssasServerName};Catalog=myDatabaseName"))
using (var adomdCommand = new AdomdCommand())
{
adomdCommand.CommandText = "SELECT [CATALOG_NAME] AS [DATABASE],CUBE_CAPTION AS [CUBE/PERSPECTIVE],BASE_CUBE_NAME FROM $system.MDSchema_Cubes WHERE CUBE_SOURCE = 1";
adomdCommand.Connection = adomdConnection;
adomdConnection.Open();
adomdCommand.ExecuteNonQuery();
Log("ExecuteNonQuery call succeeded so the user has access");
hasAccess = 1;
}
}
catch (Exception ex)
{
Log("There was an error firing query on the database in SSAS server. so user doesn't have access");
}
return hasAccess;
}
现在,为了利用基于 Windows 集成安全的身份验证,我们可以通过两种方式运行此代码:
- Out-Proc Impersonation:将此代码放入控制台应用程序中。当我们右键单击 exe 时,使用上下文菜单中的“以不同用户身份运行”选项。放置用户 Y(比方说)的凭据,以便应用程序在用户 Y 的上下文中启动,我们需要验证 SSAS 服务器上的访问权限。ADOMD.Net 将在使用 Windows Integrated Security for SSAS 服务器连接时使用用户 Y 的身份。如果代码成功,则用户可以访问。
- In-Proc Impersonation:另一种情况可能是您以用户 X 的身份运行应用程序,但您想测试用户 Y 的访问权限。在这里,您实际上需要在运行上述代码时进行就地模拟。为了实现它,我使用了一个著名的 NuGet 包“Simple Impersonation”,它使用默认的 .Net 库类
WindowsImpersonationContext
和WindowsIdentity
. 这个 NuGet 包的创建者首先在这里发布了一个很好的答案。
SQL Server Profiler 中的观察:模拟 user 后,如果您捕获会话Y
,您将清楚地看到 MDX 查询在 user 的上下文中被触发,Y
如下所示:

警告和担忧:
- 我在使用这种进程内模拟时遇到的一个问题是,如果 SSAS 服务器位于运行应用程序代码的同一台机器上,它就不起作用。这是由于
LogonUser
在 NuGete 包的模拟调用期间调用的本机 API(使用 LOGON32_LOGON_NEW_CREDENTIALS LogonType)的固有行为。您可以尝试此处详述的其他登录类型,您需要哪些套件。
- 您需要用户的密码以及域名和用户名来进行模拟。
对于 ADOMD.Net v13.x 及更高版本
然后,我在这里ChangeEffectiveUser
的 MSDN 上看到了这个 API 文档。但是,智能感知没有显示这个 API。然后我发现这个 API 是在 SQL Server 2016 版本中添加到 ADOMD.Net 中的。有多种方法可以获取最新版本:
C:\Program Files\Microsoft.NET\ADOMD.NET\130\Microsoft.AnalysisServices.AdomdClient.dll
我不确定是谁在这个位置转储了这个文件。它是 Microsoft.Net 扩展或 SQL Server 安装的一部分。
- 在 Microsoft SQL Server 的安装文件夹中。我在路径上得到它 -
C:\Program Files\Microsoft SQL Server\130\Setup Bootstrap\Update Cache\KB3182545\ServicePack\x64\Microsoft.AnalysisServices.AdomdClient.dll
- NuGet 包在这里。由于某些奇怪的原因,MS 最熟悉的 ADOMD.Net v13.x 的 NuGet 包被命名为
Unofficial.Microsoft.AnalysisServices.AdomdClient
. 不知道为什么他们引入了一个单独的带有前缀的 NuGet 包,而这应该只是此处Unofficial
现有 NuGet 包的下一个Microsoft.AnalysisServices.AdomdClient
版本。
ChangeEffectiveUser
因此,clas上最新版本中的新 APIAdomdConnection
可以很容易地模拟任何用户,如下所示:
adomdConnection.Open();
//impersonate the user after opening the connection
adomdConnection.ChangeEffectiveUser("domainName\UserNameBeingImpersonated");
//now the query gets fired in the context of the impersonated user
adomdCommand.ExecuteNonQuery();
观察 SQL Server Profiler 中的模拟:尽管我在 SQL Server Profiler 中观察到的一个特殊现象是,被触发的查询日志仍然显示运行应用程序进程的原始用户的名称。

因此,为了检查是否发生了模拟,我domainName\UserNameBeingImpersonated
从 SSAS 服务器中删除了用户的访问权限。之后,当我再次运行上述代码时,它导致异常,其消息清楚地指出 - the user domainName\UserNameBeingImpersonated doesn't have permission on the SSAS server or the database doesn't exist
。此错误消息清楚地表明模拟正在起作用。
这种方法的优点和向后兼容性:
- 虽然 API 是最近才出现的,因为它是在 SQL Server 2016 中提出的,但我也能够成功地将它与 SSAS 服务器 2014 一起使用。所以它看起来相当向后兼容。
- 无论您的 SSAS 服务器是本地还是远程,此 API 都有效。
- 您只需要域名和用户名即可进行模拟。无需密码。
如果我们只是想检查 SSAS 服务器上的访问而不涉及 SSAS 服务器上存在的任何数据库,该怎么办?
- 将连接字符串更改为不涉及任何数据库。删除
Catalog
以下连接字符串的键 - “provider=olap;datasource={ssasServerName};”
- 改为触发以下查询以检查访问权限 -
SELECT * FROM $System.discover_locks
在帖子最初显示的代码片段中。