Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.
Hello Everyone,
I am attempting to implement RLS in our .Net Core application of embedding power BI. here is our current TokenDataCall
/// <summary> /// Gets Token Credentials and access token for use with authenticating PowerBi api calls /// </summary> /// <returns></returns> public async Task<(TokenCredentials tokenCredentials, string accessToken)> GetTokenDataAsync() { try { var authorityUrl = $"{_azureSettings.Instance}{_azureSettings.TenantId}/oauth2/token"; var oauthEndpoint = new Uri(authorityUrl); using (var client = new HttpClient()) { var result = await client.PostAsync(oauthEndpoint, new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("resource", _powerBiSettings.ResourceAddress), new KeyValuePair<string, string>("client_id", _azureSettings.ClientId), new KeyValuePair<string, string>("grant_type", "password"), new KeyValuePair<string, string>("username", _powerBiSettings.MasterUser), new KeyValuePair<string, string>("password", _powerBiSettings.MasterKey), new KeyValuePair<string, string>("scope", "openid"), })); var content = await result.Content.ReadAsStringAsync(); var authenticationResult = JsonConvert.DeserializeObject<OAuthResult>(content); return (new TokenCredentials(authenticationResult.AccessToken, _azureSettings.TokenType), authenticationResult.AccessToken); } } catch (Exception ex) { _logger.LogError(ex, ex.Message); throw; } } private class OAuthResult { [JsonProperty("token_type")] public string TokenType { get; set; } [JsonProperty("scope")] public string Scope { get; set; } [JsonProperty("expires_in")] public int ExpiresIn { get; set; } [JsonProperty("ext_expires_in")] public int ExtExpiresIn { get; set; } [JsonProperty("expires_on")] public int ExpiresOn { get; set; } [JsonProperty("not_before")] public int NotBefore { get; set; } [JsonProperty("resource")] public Uri Resource { get; set; } [JsonProperty("access_token")] public string AccessToken { get; set; } [JsonProperty("refresh_token")] public string RefreshToken { get; set; } }
I haven't found any documentation on how to use this token call to pass in the "Role" and "username" parameters found here.
https://docs.microsoft.com/en-us/power-bi/developer/embedded-row-level-security
Is there anyway to add those into the dictionary and for it to return the correct report access token with filtered data?
Thanks,
Solved! Go to Solution.
Hi @Anonymous,
If you use the Rest API, it could be like below. Please refer to #applying-user-and-role-to-an-embed-token.
{ "accessLevel": "View", "identities": [ { "username": "EffectiveIdentity", "roles": [ "Role1", "Role2" ], "datasets": [ "fe0a1aeb-f6a4-4b27-a2d3-b5df3bb28bdc" ] } ] }
I tested it successfully with Postman.
Best Regards,
Dale
Fixed,
I was confused because we were embedding the report through the Azure AD token, I am not sure how to implement RLS through the Azure AD token, like so.
try { var tokenData = await _authenticationHandler.GetTokenDataAsync(); using (var client = new PowerBIClient(new Uri(_powerBiSettings.MainAddress), tokenData.tokenCredentials)) { var report = await client.Reports.GetReportAsync(_powerBiSettings.GroupId, id.ToString()); return new ReportDetail { Id = Guid.Parse(report.Id), Name = report.Name, EmbedUrl = report.EmbedUrl, AccessToken = tokenData.accessToken }; } }
To fix this we just imbed the power BI report token instead with RLS identity.
try { var tokenData = await _authenticationHandler.GetTokenDataAsync(); using (var client = new PowerBIClient(new Uri(_powerBiSettings.MainAddress), tokenData.tokenCredentials)) { var report = await client.Reports.GetReportAsync(_powerBiSettings.GroupId, id.ToString()); var identity = new List<EffectiveIdentity> { new EffectiveIdentity("MasterUser", //TODO: Change this to use azure identity roles: new List<string> {"User"}, datasets: new List<string> {report.DatasetId}) }; var generateTokenRequestParameters = new GenerateTokenRequest("view", null, identities: identity); var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(_powerBiSettings.GroupId, report.Id, generateTokenRequestParameters); return new ReportDetail { Id = Guid.Parse(report.Id), Name = report.Name, EmbedUrl = report.EmbedUrl, AccessToken = tokenResponse.Token }; } }
Be sure to set the token type to embed rather than AAD token in the Javascript config.
Thanks for your help.
Hi @Anonymous,
If you use the Rest API, it could be like below. Please refer to #applying-user-and-role-to-an-embed-token.
{ "accessLevel": "View", "identities": [ { "username": "EffectiveIdentity", "roles": [ "Role1", "Role2" ], "datasets": [ "fe0a1aeb-f6a4-4b27-a2d3-b5df3bb28bdc" ] } ] }
I tested it successfully with Postman.
Best Regards,
Dale
Fixed,
I was confused because we were embedding the report through the Azure AD token, I am not sure how to implement RLS through the Azure AD token, like so.
try { var tokenData = await _authenticationHandler.GetTokenDataAsync(); using (var client = new PowerBIClient(new Uri(_powerBiSettings.MainAddress), tokenData.tokenCredentials)) { var report = await client.Reports.GetReportAsync(_powerBiSettings.GroupId, id.ToString()); return new ReportDetail { Id = Guid.Parse(report.Id), Name = report.Name, EmbedUrl = report.EmbedUrl, AccessToken = tokenData.accessToken }; } }
To fix this we just imbed the power BI report token instead with RLS identity.
try { var tokenData = await _authenticationHandler.GetTokenDataAsync(); using (var client = new PowerBIClient(new Uri(_powerBiSettings.MainAddress), tokenData.tokenCredentials)) { var report = await client.Reports.GetReportAsync(_powerBiSettings.GroupId, id.ToString()); var identity = new List<EffectiveIdentity> { new EffectiveIdentity("MasterUser", //TODO: Change this to use azure identity roles: new List<string> {"User"}, datasets: new List<string> {report.DatasetId}) }; var generateTokenRequestParameters = new GenerateTokenRequest("view", null, identities: identity); var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(_powerBiSettings.GroupId, report.Id, generateTokenRequestParameters); return new ReportDetail { Id = Guid.Parse(report.Id), Name = report.Name, EmbedUrl = report.EmbedUrl, AccessToken = tokenResponse.Token }; } }
Be sure to set the token type to embed rather than AAD token in the Javascript config.
Thanks for your help.
Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City
Check out the April 2024 Power BI update to learn about new features.
User | Count |
---|---|
13 | |
2 | |
2 | |
1 | |
1 |