Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!

Reply
Kvotava
Frequent Visitor

powerbi embedded embed token: setting access level

I am having trouble getting the access level working when trying to create a power BI embedded token. I can create the token just fine, but no matter what I put in for the Access Level the client is able to access all the modes (Create, View, and Edit).It was my impression that the accessLevel would limit what the client can access, but this does not seem to be the case. Any insight would be greatly appreciated.

 

Here is what I am doing:

 

function getEmbedToken(accessToken, groupId, reportId, datasetId, mode) {
  return new Promise((resolve, reject) => {
    let url =
        "https://api.powerbi.com/v1.0/myorg/groups/" +
        groupId +
        "/reports/" +
        reportId +
        "/GenerateToken";

  var formData = {
      accessLevel: "View",
      datasetId: datasetId,
      allowSaveAs: "true",
      identities: [
        {
          username: "user@user.com",
          datasets: [datasetId],
          customData: "MyCustomData"
        }
      ]
    };

    axios({
      method: "post",
      url: url,
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer " + accessToken
      },
      data: formData
    })
      .then(response => {
        // console.log(response);
        response.data.accessToken = accessToken;
        resolve(response);
      })
      .catch(function(response) {
        //handle error
        console.log(response);
        reject("Failed to get EmbedToken");
      });
  });
}
 I tried using "view" as well as "View" but that did not make any difference.
1 ACCEPTED SOLUTION
Kvotava
Frequent Visitor

Ok I figured it out and it has to do with a misunderstanding on my part. The accessLevel does not prevent a user from going into Edit mode they just prevent a user from being able to save (once in Edit mode). 

 

Anywhoo more clear now. Thanks for your help Ted!

 

 

View solution in original post

3 REPLIES 3
Kvotava
Frequent Visitor

Ok I figured it out and it has to do with a misunderstanding on my part. The accessLevel does not prevent a user from going into Edit mode they just prevent a user from being able to save (once in Edit mode). 

 

Anywhoo more clear now. Thanks for your help Ted!

 

 

TedPattison
Employee
Employee

This looks OK. I cannot see any problems with this code. Can you show the other code where you use the powerbi client to embed the object.

 

Also, have you considered using the Power BI API SDK? This will make this code much easier to write. Here is an example.

 

public static ReportEmbeddingData GetReportEmbeddingData() {

  PowerBIClient pbiClient = GetPowerBiClient();

  var report = pbiClient.Reports.GetReportInGroup(workspaceId, reportId);
  var embedUrl = report.EmbedUrl;
  var reportName = report.Name;

  // create token request object
  GenerateTokenRequest generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");

  // call to Power BI Service API and pass GenerateTokenRequest object to generate embed token
  string embedToken = pbiClient.Reports.GenerateTokenInGroup(workspaceId,
                                                              report.Id,
                                                              generateTokenRequestParameters).Token;

  return new ReportEmbeddingData {
    reportId = reportId,
    reportName = reportName,
    embedUrl = embedUrl,
    accessToken = embedToken
  };

}

 

 

I am using javascript so the SDK is not available to me.

 

Here is the component that I am using (This is in React)

 

 

import React, { Component } from "react";
import PropTypes from "prop-types";
import pbi from "powerbi-client";

/* global powerbi */
export class PBIReport extends Component {
  constructor(props) {
    super(props);
    this.component = null;
    let setViewMode;

    if (this.props.mode === "Edit") {
      setViewMode = pbi.models.ViewMode.Edit;
    } else {
      setViewMode = pbi.models.ViewMode.View;
    }
    this.state = {
      type: "report",
      tokenType: pbi.models.TokenType.Embed,
      viewMode: setViewMode,
      permissions: pbi.models.Permissions.All,
      settings: {
        filterPaneEnabled: this.props.filterPaneEnabled,
        navContentPaneEnabled: this.props.navContentPaneEnabled
      },
      rendered: false
    };
  }

  componentDidMount() {
    this.updateState(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this.updateState(nextProps);
  }

  componentDidUpdate() {
    if (this.validateConfig(this.state) && !this.state.rendered) {
      return this.embed(this.state);
    }
  }

  componentWillUnmount() {
    this.reset();
  }

  embed(config) {
    var _this = this;
    this.component = powerbi.embed(this.rootElement, config);
    if (this.props.onEmbedded) {
      this.props.onEmbedded(this.component);
    }

    this.component.on(
      "rendered",
      function() {
        if (_this.state.rendered === false) _this.setState({ rendered: true });
      },
      _this
    );
    return this.component;
  }

  reset() {
    powerbi.reset(this.rootElement);
    this.component = null;
  }

  updateState(props) {
    const nextState = Object.assign({}, this.state, props, {
      settings: {
        filterPaneEnabled: this.props.filterPaneEnabled,
        navContentPaneEnabled: this.props.navContentPaneEnabled
      }
    });
    /**
     * This property must be removed from the state object so that it doesn't get used in the embedConfig.
     * This would be passed to `powerbi.embed(element, embedConfig)` and attempted to be sent over postMessage;
     * however, functions cannot be cloned and it will fail.
     */
    delete nextState.onEmbedded;
    this.setState(nextState);
  }

  validateConfig(config) {
    const errors = pbi.models.validateReportLoad(config);
    return errors === undefined;
  }

  render() {
    return (
      <div className="powerbi-frame">
        <div className="powerbi-frame" ref={ref => (this.rootElement = ref)} />
      </div>
    );
  }
}

PBIReport.propTypes = {
  accessToken: PropTypes.string,
  embedUrl: PropTypes.string
};

export default PBIReport;

 

 

And here is the Report Component the uses the PBIReport component

 

 

import React, { Component } from "react";
import PBIReport from "components/powerBI/components/powerbi-report";

class Report extends Component {
  constructor(props) {
    super(props);

    this.state = {
      mode: "Edit"
    };
  }

  onEmbedded(embed) {
    console.log(`Report embedded: `, embed, this);
  }
  render() {
    return (
      <div style={{ height: "100%", minHeight: "100%" }}>
        <div style={{ height: "100%" }}>
          <PBIReport
            id={curRptConfig.id}
            embedUrl={"https://app.powerbi.com/reportEmbed"}
            accessToken={embeddedToken}
            filterPaneEnabled={false}
            navContentPaneEnabled={true}
            onEmbedded={this.onEmbedded}
            mode={mode}
          />
        </div>
      </div>
    );
  }
}

export default Report;

The id and accessToken are returned from the Server partially using the method i posted in the original post.

 

I would think if the getEmbedToken function was getting an embed Token with a "View" accessLevel that the power bi service would throw back an error if you tried to access the "Edit" view. But, that does not seem to be happening. 

 

Thanks for the help!

 

Helpful resources

Announcements
April AMA free

Microsoft Fabric AMA Livestream

Join us Tuesday, April 09, 9:00 – 10:00 AM PST for a live, expert-led Q&A session on all things Microsoft Fabric!

March Fabric Community Update

Fabric Community Update - March 2024

Find out what's new and trending in the Fabric Community.