在AAS/Power BI Cube连接字符串中使用MSAL访问令牌连接失败
需要使用针对Power BI访问范围生成的MSAL访问令牌查询Power BI数据集,目前MSAL访问令牌可正常生成,但使用构造的连接字符串通过OleDB创建连接始终失败。使用交互式安全认证可正常建立连接,通过App Reg(应用注册)的服务主体方式无法连通。
现有实现代码
// 服务类型解析函数 public static string ResolveCubeType (string cubeServerName) { // 根据服务地址判断是Power BI还是Azure Analysis Services string cubeType = cubeServerName.Contains("powerbi") ? "powerbi":"aas"; return cubeType; } // 资源URI解析函数 public static string ResolveResourceUri(string cubeType, string aasRegion) { // 根据服务类型拼接对应资源URI string resourceUri = ( cubeType == "powerbi" ? "https://analysis.windows.net/powerbi/api":$"https://{aasRegion}.asazure.windows.net" ); return resourceUri; } // 认证权威地址解析函数 public static string ResolveAuthorityUri(string tenantId) { // 拼接对应租户的微软登录地址 string authorityUri = $"https://login.microsoftonline.com/{tenantId}"; return authorityUri; } // 访问权限范围解析函数 public static string ResolveAccessScope(string resourceUri) { // 拼接默认权限范围 string accessScope = $"{resourceUri}/.default"; return accessScope; } // 访问令牌生成函数 public static async Task<string> GenerateAccessToken( string accessScope, string clientId, string clientSecret, string authorityUri, string redirectUri ){ List<string> scopeList = new List<string>(); scopeList.Add(accessScope); // 初始化机密客户端 var confidentialClient = ConfidentialClientApplicationBuilder .Create(clientId) .WithClientSecret(clientSecret) .WithAuthority(new Uri(authorityUri)) .WithRedirectUri(redirectUri) .Build(); // 发起客户端凭证流令牌请求 var accessTokenRequest = confidentialClient.AcquireTokenForClient(scopeList); var authResult = await accessTokenRequest.ExecuteAsync(); return authResult.AccessToken.ToString(); } // 主逻辑片段 string adlsUri = $"https://{adlsStorageAccountName}.dfs.core.windows.net"; // 解析服务类型 string cubeType = ResolveCubeType(cubeServer); // 解析资源URI string cubeResourceUri = ResolveResourceUri(cubeType, "australiaeast"); // 解析访问范围 string accessScope = ResolveAccessScope(cubeResourceUri); // 解析认证地址 string authorityUri = ResolveAuthorityUri(tenantId.Value.ToString()); // 配置重定向地址 string redirectUri = "urn:ietf:wg:oauth:2.0:oob"; // 获取MSAL访问令牌 string accessToken = await GenerateAccessToken( accessScope, clientId.Value.ToString(), clientSecret.Value.ToString(), authorityUri, redirectUri ); // 构造连接字符串 string connectionString = $"Provider=MSOLAP.8;" + $"Data Source={cubeServer};" + "Update Isolation Level=2;" + $"Initial Catalog={cubeName};" + $"User ID=;" + $"Password={accessToken};" + $"Persist Security Info=True;" + $"Impersonation Level=Impersonate"; // 创建OLEDB连接 using (var connection = new OleDbConnection(connectionString)) //using (var connection = new AdomdConnection(connectionString)) { bool exceptionCaught = false; try { connection.Open(); } catch(Exception e) { Console.WriteLine("{0} Error:", e); exceptionCaught = true; return ""; }
相关环境信息
- 当前使用的MSOLAP驱动版本:

- 补充测试结果:通过PowerShell也无法连接对应工作区,报错截图如下:

按以下顺序逐一排查修复:
- 升级MSOLAP驱动版本
你当前使用的MSOLAP.8是对应SQL Server 2016的老旧版本,完全不支持Azure AD服务主体的现代认证场景,卸载旧版本后安装16.0以上版本的Microsoft Analysis Services OLE DB Provider,优先选择最新正式版,老版本驱动无法识别传入的AAD访问令牌。 - 修正连接字符串配置
现有连接字符串中User ID留空是核心错误,使用服务主体+访问令牌连接时,必须按固定格式填写User ID,否则驱动无法识别认证类型。修正后的连接字符串片段如下:
string connectionString = $"Provider=MSOLAP;" + // 不指定小版本号,自动调用本机最新版驱动 $"Data Source={cubeServer};" + "Update Isolation Level=2;" + $"Initial Catalog={cubeName};" + $"User ID=app:{clientId.Value}@{tenantId.Value};" + // 必须按app:客户端ID@租户ID格式填写 $"Password={accessToken};" + $"Persist Security Info=True;" + $"Impersonation Level=Impersonate";
如果使用AdomdConnection连接,连接字符串格式完全一致,兼容性比OleDB更好,优先使用AdomdConnection。
3. 开启Power BI租户级服务主体访问权限
登录Power BI管理后台,进入租户设置,找到「开发人员设置」分类下的「允许服务主体使用Power BI API」选项,开启开关。注意不要直接开放给所有服务主体,将你使用的应用注册对应的服务主体加入指定安全组,再将安全组添加到允许列表中。
4. 配置工作区访问权限
服务主体是独立的身份,和你个人交互式登录的账号权限不互通,必须进入对应Power BI工作区的「访问」设置,将服务主体(或服务主体所在的安全组)添加为工作区成员,至少授予「查看者」以上权限,如果需要写入数据集则授予「参与者」「成员」或「管理员」权限。
5. 检查应用注册权限配置
回到Azure AD应用注册页面,进入「API权限」配置,添加Power BI Service的应用程序类型权限(不要加委托权限,客户端凭证流不识别委托权限),至少授予Dataset.Read.All权限,如果需要写入则授予Dataset.ReadWrite.All,添加完成后点击「授予管理员同意」,确保令牌携带对应权限声明。
6. 确认XMLA端点开启状态
进入对应Power BI工作区的设置页面,找到「Premium」选项卡,确认XMLA端点设置为「只读」或「读写」,未开启XMLA端点时无法通过连接字符串访问数据集。
7. 校验XMLA端点地址正确性
确认你使用的cubeServer地址格式正确,公有云Power BI的XMLA端点格式为powerbi://api.powerbi.com/v1.0/myorg/你的工作区名称,不要使用自定义的错误地址。
内容的提问来源于stack exchange,提问作者hello_friend

