3 min read
Power BI Embed for Organization: Internal Analytics Integration
Embed for organization (User Owns Data) integrates Power BI into internal applications where users authenticate with their Azure AD credentials. It leverages existing Power BI Pro or Premium licenses.
When to Use
use_cases:
- Internal portals
- SharePoint integration
- Custom line-of-business apps
- Teams applications
requirements:
- Users have Power BI Pro or Premium Per User licenses
- Azure AD authentication
- Report sharing permissions
Implementation
Azure AD App Registration
# Register application
az ad app create \
--display-name "Internal-PowerBI-App" \
--reply-urls "https://internalapp.company.com/callback" \
--available-to-other-tenants false
React with MSAL
import { useMsal } from "@azure/msal-react";
import { PowerBIEmbed } from 'powerbi-client-react';
import { models } from 'powerbi-client';
function InternalDashboard() {
const { instance, accounts } = useMsal();
const [accessToken, setAccessToken] = useState(null);
useEffect(() => {
async function acquireToken() {
const request = {
scopes: ["https://analysis.windows.net/powerbi/api/.default"],
account: accounts[0]
};
try {
const response = await instance.acquireTokenSilent(request);
setAccessToken(response.accessToken);
} catch (error) {
const response = await instance.acquireTokenPopup(request);
setAccessToken(response.accessToken);
}
}
if (accounts.length > 0) {
acquireToken();
}
}, [instance, accounts]);
if (!accessToken) return <div>Authenticating...</div>;
return (
<PowerBIEmbed
embedConfig={{
type: 'report',
id: 'report-id',
embedUrl: 'https://app.powerbi.com/reportEmbed?reportId=...',
accessToken: accessToken,
tokenType: models.TokenType.Aad, // AAD token
settings: {
panes: {
filters: { expanded: false },
pageNavigation: { visible: true }
}
}
}}
cssClassName="report-container"
/>
);
}
Backend Token Acquisition (C#)
public class PowerBIService
{
private readonly IConfidentialClientApplication _app;
public PowerBIService(IConfiguration config)
{
_app = ConfidentialClientApplicationBuilder
.Create(config["AzureAd:ClientId"])
.WithClientSecret(config["AzureAd:ClientSecret"])
.WithAuthority(new Uri($"https://login.microsoftonline.com/{config["AzureAd:TenantId"]}"))
.Build();
}
public async Task<string> GetUserToken(string userAssertion)
{
// On-behalf-of flow
var result = await _app.AcquireTokenOnBehalfOf(
new[] { "https://analysis.windows.net/powerbi/api/.default" },
new UserAssertion(userAssertion)
).ExecuteAsync();
return result.AccessToken;
}
}
SharePoint Integration
<!-- SharePoint Web Part -->
<script src="https://cdn.powerbi.com/libs/powerbi-client/2.19.1/powerbi.min.js"></script>
<div id="embedContainer"></div>
<script>
// Get SharePoint context token
async function getToken() {
const tokenResponse = await fetch('/_api/SP.OAuth.Token/Acquire', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
resource: 'https://analysis.windows.net/powerbi/api'
})
});
return (await tokenResponse.json()).access_token;
}
async function embedReport() {
const token = await getToken();
const config = {
type: 'report',
tokenType: powerbi.models.TokenType.Aad,
accessToken: token,
embedUrl: 'https://app.powerbi.com/reportEmbed?reportId=...',
id: 'report-id'
};
powerbi.embed(document.getElementById('embedContainer'), config);
}
embedReport();
</script>
Teams Tab Integration
import { app, authentication } from "@microsoft/teams-js";
import { PowerBIEmbed } from 'powerbi-client-react';
function TeamsTab() {
const [token, setToken] = useState(null);
useEffect(() => {
app.initialize().then(() => {
authentication.getAuthToken({
resources: ["https://analysis.windows.net/powerbi/api"]
}).then(setToken);
});
}, []);
if (!token) return <div>Loading...</div>;
return (
<PowerBIEmbed
embedConfig={{
type: 'report',
accessToken: token,
tokenType: 1, // AAD
embedUrl: embedUrl,
id: reportId
}}
/>
);
}
Permission Management
// Check user permissions before embedding
public async Task<bool> UserCanAccessReport(string userId, string reportId)
{
var client = await GetAuthenticatedClient(userId);
try
{
var report = await client.Reports.GetReportAsync(
Guid.Parse(_workspaceId),
Guid.Parse(reportId)
);
return true;
}
catch (HttpOperationException ex) when (ex.Response.StatusCode == HttpStatusCode.Forbidden)
{
return false;
}
}
Best Practices
authentication:
- Use MSAL for token acquisition
- Implement token caching
- Handle token refresh gracefully
permissions:
- Verify user access before embedding
- Respect Power BI sharing settings
- Use workspaces for permission management
user_experience:
- Match app theme with Power BI theme
- Handle authentication errors gracefully
- Provide fallback for unlicensed users
Conclusion
Embed for organization leverages existing Power BI investments:
- Seamless Azure AD integration
- Respects organizational security policies
- No additional capacity costs
- Full Power BI feature set
It’s ideal for internal applications requiring rich analytics.