Forum Discussion
Embedding with RLS: NulLReferenceException when Generating Token
I am getting a nullreferenceexception on the line
var accessToken = "@Model.EmbedToken.Token";
The report was rendering properly before attempting RLS. Here's my controller:
else
{
// Generate Embed Token for reports without effective identities.
generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view", identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: System.Web.HttpContext.Current.User.Identity.GetUserId(), roles: new List<string> { "allusers" }, datasets: new List<string> { "12dac33c-af76-4e1b-b064-57d837679b0c" }) });
}
var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(GroupId, report.Id, generateTokenRequestParameters);
6 Replies
- v-micsh-msftMicrosoft Employee
Where did you implement the controller?
By the way, could you please share the full code for the generateToken part?
If you are using the App owns Data sample, make sure you have followed the steps mentioned in the article below:
https://docs.microsoft.com/en-us/power-bi/developer/embedded-row-level-security
Just replace:
// Generate Embed Token. var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view"); var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(GroupId, report.Id, generateTokenRequestParameters);
with the code below:
var generateTokenRequestParameters = new GenerateTokenRequest("View", null, identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "username", roles: new List<string> { "roleA", "roleB" }, datasets: new List<string> { "datasetId" }) }); var tokenResponse = await client.Reports.GenerateTokenInGroupAsync("groupId", "reportId", generateTokenRequestParameters);Regards,
Michael
- ats1958Helper II
I'm not sure what you mean by where the controller is implemented. But my full controller code is below. The only thing that have changed are the relevant lines which I already posted.
I did follow the steps in the article you attached.
Thanks!
[Authorize] public async Task<ActionResult> Index(string username, string roles) { var result = new EmbedConfig(); try { result = new EmbedConfig { Username = username, Roles = roles }; var error = GetWebConfigErrors(); if (error != null) { result.ErrorMessage = error; return View(result); } // Create a user password cradentials. var credential = new UserPasswordCredential(Username, Password); // Authenticate using created credentials var authenticationContext = new AuthenticationContext(AuthorityUrl); var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ClientId, credential); if (authenticationResult == null) { result.ErrorMessage = "Authentication Failed."; return View(result); } var tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, "Bearer"); // Create a Power BI Client object. It will be used to call Power BI APIs. using (var client = new PowerBIClient(new Uri(ApiUrl), tokenCredentials)) { // Get a list of reports. var reports = await client.Reports.GetReportsInGroupAsync(GroupId); Report report; if (string.IsNullOrEmpty(ReportId)) { // Get the first report in the group. report = reports.Value.FirstOrDefault(); } else { report = reports.Value.FirstOrDefault(r => r.Id == ReportId); } if (report == null) { result.ErrorMessage = "Group has no reports."; return View(result); } var datasets = await client.Datasets.GetDatasetByIdInGroupAsync(GroupId, report.DatasetId); result.IsEffectiveIdentityRequired = datasets.IsEffectiveIdentityRequired; result.IsEffectiveIdentityRolesRequired = datasets.IsEffectiveIdentityRolesRequired; GenerateTokenRequest generateTokenRequestParameters; // This is how you create embed token with effective identities if (!string.IsNullOrEmpty(username)) { var rls = new EffectiveIdentity(username, new List<string> { report.DatasetId }); if (!string.IsNullOrWhiteSpace(roles)) { var rolesList = new List<string>(); rolesList.AddRange(roles.Split(',')); rls.Roles = rolesList; } // Generate Embed Token with effective identities. generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view", identities: new List<EffectiveIdentity> { rls }); } else { // Generate Embed Token for reports without effective identities. generateTokenRequestParameters = new GenerateTokenRequest("View", null, identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: System.Web.HttpContext.Current.User.Identity.GetUserId(), roles: new List<string> { "allusers" }, datasets: new List<string> { "12dac33c-af76-4e1b-b064-57d837679b0c" }) }); } var tokenResponse = await client.Reports.GenerateTokenInGroupAsync("groupId", "reportId", generateTokenRequestParameters); if (tokenResponse == null) { result.ErrorMessage = "Failed to generate embed token."; return View(result); } // Generate Embed Configuration. result.EmbedToken = tokenResponse; result.EmbedUrl = report.EmbedUrl; result.Id = report.Id; return View(result); } } catch (HttpOperationException exc) { result.ErrorMessage = string.Format("Status: {0} ({1})\r\nResponse: {2}\r\nRequestId: {3}", exc.Response.StatusCode, (int)exc.Response.StatusCode, exc.Response.Content, exc.Response.Headers["RequestId"].FirstOrDefault()); } catch (Exception exc) { result.ErrorMessage = exc.ToString(); } return View(result); }- ats1958Helper II
I doubt this is the issue, but I'm using a Guid as the username. Perhaps the length of that is the issue. Here's a sample one:
845cc21b-eeca-49a6-b2b7-17a8ac09de7f