From 4d5c95839cb04f01c7a0856dc78fc3dbce004cab Mon Sep 17 00:00:00 2001 From: Atharva Bapat Date: Wed, 9 Feb 2022 13:00:02 +0000 Subject: [PATCH 1/8] Merged PR 234536: [Developer Samples]: Add config folders and update variable names --- .../AppOwnsData/Models/AzureAd.cs | 6 +++--- .../AppOwnsData/Services/AadService.cs | 10 +++++----- .../AppOwnsData/Services/ConfigValidatorService.cs | 6 +++--- .../AppOwnsData/Services/PbiEmbedService.cs | 4 ++-- .../AppOwnsData/appsettings.json | 4 ++-- .../Power BI Global/appsettings.json | 5 +++++ .../Power BI US Government/appsettings.json | 5 +++++ .../Power BI in Germany/appsettings.json | 5 +++++ .../appsettings.json | 5 +++++ .../UserOwnsData/Controllers/HomeController.cs | 2 +- .../UserOwnsData/appsettings.json | 2 +- .../Power BI Global/appsettings.json | 6 ++++++ .../Power BI US Government/appsettings.json | 6 ++++++ .../Power BI in Germany/appsettings.json | 6 ++++++ .../appsettings.json | 6 ++++++ .../EncryptCredentials/Models/AzureAd.cs | 6 +++--- .../EncryptCredentials/Services/AadService.cs | 10 +++++----- .../EncryptCredentials/Services/ConfigValidator.cs | 6 +++--- .../EncryptCredentials/Services/PowerBIService.cs | 4 ++-- .../EncryptCredentials/appsettings.json | 4 ++-- .../AppOwnsData/Services/AadService.cs | 2 +- .../AppOwnsData/Services/EmbedService.cs | 4 ++-- .../Embed for your customers/AppOwnsData/Web.config | 4 ++-- .../CloudConfigs/Power BI Global/Cloud.config | 4 ++-- .../CloudConfigs/Power BI US Government/Cloud.config | 6 +++--- .../CloudConfigs/Power BI in Germany/Cloud.config | 4 ++-- .../Cloud.config | 4 ++-- .../UserOwnsData/Services/ConfigValidatorService.cs | 8 ++++---- .../Services/Security/OwinOpenIdConnect.cs | 2 +- .../Services/Security/PowerBiPermissionScopes.cs | 8 ++++---- .../UserOwnsData/Web.config | 4 ++-- .../com/embedsample/appownsdata/config/Config.java | 2 +- .../appownsdata/services/AzureADService.java | 4 ++-- .../CloudConfigs/Power BI Global/Config.java | 12 ++++++++++++ .../CloudConfigs/Power BI US Government/Config.java | 12 ++++++++++++ .../CloudConfigs/Power BI in Germany/Config.java | 12 ++++++++++++ .../Config.java | 12 ++++++++++++ .../encryptcredential/config/Config.java | 2 +- .../encryptcredential/services/AzureADService.java | 4 ++-- .../AppOwnsData/config/config.json | 6 +++--- .../AppOwnsData/src/authentication.js | 6 +++--- .../AppOwnsData/src/utils.js | 4 ++-- .../Embed for your customers/AppOwnsData/config.py | 6 +++--- .../AppOwnsData/services/aadservice.py | 10 +++++----- Python/Embed for your customers/AppOwnsData/utils.py | 4 ++-- .../CloudConfigs/Power BI Global/config.py | 12 ++++++++++++ .../CloudConfigs/Power BI US Government/config.py | 12 ++++++++++++ .../CloudConfigs/Power BI in Germany/config.py | 12 ++++++++++++ .../Power BI operated by 21Vianet in China/config.py | 12 ++++++++++++ .../Encrypt credentials/Encryption sample/config.py | 6 +++--- .../Encryption sample/services/aadservice.py | 4 ++-- .../Encrypt credentials/Encryption sample/utils.py | 6 +++--- React-TS/CloudConfigs/Power BI Global/Config.ts | 10 ++++++++++ .../CloudConfigs/Power BI US Government/Config.ts | 10 ++++++++++ React-TS/CloudConfigs/Power BI in Germany/Config.ts | 10 ++++++++++ .../Power BI operated by 21Vianet in China/Config.ts | 10 ++++++++++ .../UserOwnsData/src/App.tsx | 2 +- .../UserOwnsData/src/Config.ts | 4 ++-- 58 files changed, 272 insertions(+), 92 deletions(-) create mode 100644 .NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json create mode 100644 .NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json create mode 100644 .NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json create mode 100644 .NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json create mode 100644 .NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json create mode 100644 .NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json create mode 100644 .NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json create mode 100644 .NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json create mode 100644 Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java create mode 100644 Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java create mode 100644 Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java create mode 100644 Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java create mode 100644 Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py create mode 100644 Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py create mode 100644 Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py create mode 100644 Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py create mode 100644 React-TS/CloudConfigs/Power BI Global/Config.ts create mode 100644 React-TS/CloudConfigs/Power BI US Government/Config.ts create mode 100644 React-TS/CloudConfigs/Power BI in Germany/Config.ts create mode 100644 React-TS/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts diff --git a/.NET Core/Embed for your customers/AppOwnsData/Models/AzureAd.cs b/.NET Core/Embed for your customers/AppOwnsData/Models/AzureAd.cs index 245f616b..e9c571f0 100644 --- a/.NET Core/Embed for your customers/AppOwnsData/Models/AzureAd.cs +++ b/.NET Core/Embed for your customers/AppOwnsData/Models/AzureAd.cs @@ -11,7 +11,7 @@ public class AzureAd public string AuthenticationMode { get; set; } // URL used for initiating authorization request - public string AuthorityUri { get; set; } + public string AuthorityUrl { get; set; } // Client Id (Application Id) of the AAD app public string ClientId { get; set; } @@ -19,8 +19,8 @@ public class AzureAd // Id of the Azure tenant in which AAD app is hosted. Required only for Service Principal authentication mode. public string TenantId { get; set; } - // Scope of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. - public string[] Scope { get; set; } + // ScopeBase of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + public string[] ScopeBase { get; set; } // Master user email address. Required only for MasterUser authentication mode. public string PbiUsername { get; set; } diff --git a/.NET Core/Embed for your customers/AppOwnsData/Services/AadService.cs b/.NET Core/Embed for your customers/AppOwnsData/Services/AadService.cs index 34e0538a..d604ec94 100644 --- a/.NET Core/Embed for your customers/AppOwnsData/Services/AadService.cs +++ b/.NET Core/Embed for your customers/AppOwnsData/Services/AadService.cs @@ -31,12 +31,12 @@ public string GetAccessToken() if (azureAd.Value.AuthenticationMode.Equals("masteruser", StringComparison.InvariantCultureIgnoreCase)) { // Create a public client to authorize the app with the AAD app - IPublicClientApplication clientApp = PublicClientApplicationBuilder.Create(azureAd.Value.ClientId).WithAuthority(azureAd.Value.AuthorityUri).Build(); + IPublicClientApplication clientApp = PublicClientApplicationBuilder.Create(azureAd.Value.ClientId).WithAuthority(azureAd.Value.AuthorityUrl).Build(); var userAccounts = clientApp.GetAccountsAsync().Result; try { // Retrieve Access token from cache if available - authenticationResult = clientApp.AcquireTokenSilent(azureAd.Value.Scope, userAccounts.FirstOrDefault()).ExecuteAsync().Result; + authenticationResult = clientApp.AcquireTokenSilent(azureAd.Value.ScopeBase, userAccounts.FirstOrDefault()).ExecuteAsync().Result; } catch (MsalUiRequiredException) { @@ -45,7 +45,7 @@ public string GetAccessToken() { password.AppendChar(key); } - authenticationResult = clientApp.AcquireTokenByUsernamePassword(azureAd.Value.Scope, azureAd.Value.PbiUsername, password).ExecuteAsync().Result; + authenticationResult = clientApp.AcquireTokenByUsernamePassword(azureAd.Value.ScopeBase, azureAd.Value.PbiUsername, password).ExecuteAsync().Result; } } @@ -53,7 +53,7 @@ public string GetAccessToken() else if (azureAd.Value.AuthenticationMode.Equals("serviceprincipal", StringComparison.InvariantCultureIgnoreCase)) { // For app only authentication, we need the specific tenant id in the authority url - var tenantSpecificUrl = azureAd.Value.AuthorityUri.Replace("organizations", azureAd.Value.TenantId); + var tenantSpecificUrl = azureAd.Value.AuthorityUrl.Replace("organizations", azureAd.Value.TenantId); // Create a confidential client to authorize the app with the AAD app IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder @@ -62,7 +62,7 @@ public string GetAccessToken() .WithAuthority(tenantSpecificUrl) .Build(); // Make a client call if Access token is not available in cache - authenticationResult = clientApp.AcquireTokenForClient(azureAd.Value.Scope).ExecuteAsync().Result; + authenticationResult = clientApp.AcquireTokenForClient(azureAd.Value.ScopeBase).ExecuteAsync().Result; } return authenticationResult.AccessToken; diff --git a/.NET Core/Embed for your customers/AppOwnsData/Services/ConfigValidatorService.cs b/.NET Core/Embed for your customers/AppOwnsData/Services/ConfigValidatorService.cs index ec568ffd..b6feeecd 100644 --- a/.NET Core/Embed for your customers/AppOwnsData/Services/ConfigValidatorService.cs +++ b/.NET Core/Embed for your customers/AppOwnsData/Services/ConfigValidatorService.cs @@ -26,7 +26,7 @@ public static string ValidateConfig(IOptions azureAd, IOptions { message = "Authentication mode is not set in appsettings.json file"; } - else if (string.IsNullOrWhiteSpace(azureAd.Value.AuthorityUri)) + else if (string.IsNullOrWhiteSpace(azureAd.Value.AuthorityUrl)) { message = "Authority is not set in appsettings.json file"; } @@ -38,9 +38,9 @@ public static string ValidateConfig(IOptions azureAd, IOptions { message = "Tenant Id is not set in appsettings.json file"; } - else if (azureAd.Value.Scope is null || azureAd.Value.Scope.Length == 0) + else if (azureAd.Value.ScopeBase is null || azureAd.Value.ScopeBase.Length == 0) { - message = "Scope is not set in appsettings.json file"; + message = "Scope base is not set in appsettings.json file"; } else if (string.IsNullOrWhiteSpace(powerBI.Value.WorkspaceId)) { diff --git a/.NET Core/Embed for your customers/AppOwnsData/Services/PbiEmbedService.cs b/.NET Core/Embed for your customers/AppOwnsData/Services/PbiEmbedService.cs index 5b3de38c..301d0dde 100644 --- a/.NET Core/Embed for your customers/AppOwnsData/Services/PbiEmbedService.cs +++ b/.NET Core/Embed for your customers/AppOwnsData/Services/PbiEmbedService.cs @@ -17,7 +17,7 @@ namespace AppOwnsData.Services public class PbiEmbedService { private readonly AadService aadService; - private readonly string urlPowerBiServiceApiRoot = "https://api.powerbi.com"; + private readonly string powerBiApiUrl = "https://api.powerbi.com"; public PbiEmbedService(AadService aadService) { @@ -31,7 +31,7 @@ public PbiEmbedService(AadService aadService) public PowerBIClient GetPowerBIClient() { var tokenCredentials = new TokenCredentials(aadService.GetAccessToken(), "Bearer"); - return new PowerBIClient(new Uri(urlPowerBiServiceApiRoot ), tokenCredentials); + return new PowerBIClient(new Uri(powerBiApiUrl ), tokenCredentials); } /// diff --git a/.NET Core/Embed for your customers/AppOwnsData/appsettings.json b/.NET Core/Embed for your customers/AppOwnsData/appsettings.json index ec223865..42a1d855 100644 --- a/.NET Core/Embed for your customers/AppOwnsData/appsettings.json +++ b/.NET Core/Embed for your customers/AppOwnsData/appsettings.json @@ -1,10 +1,10 @@ { "AzureAd": { "AuthenticationMode": "ServicePrincipal", - "AuthorityUri": "https://login.microsoftonline.com/organizations/", + "AuthorityUrl": "https://login.microsoftonline.com/organizations/", "ClientId": "", "TenantId": "", - "Scope": ["https://analysis.windows.net/powerbi/api/.default"], + "ScopeBase": ["https://analysis.windows.net/powerbi/api/.default"], "PbiUsername": "", "PbiPassword": "", "ClientSecret": "" diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json new file mode 100644 index 00000000..dd61bf2e --- /dev/null +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json @@ -0,0 +1,5 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.microsoftonline.com/" + } +} \ No newline at end of file diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json new file mode 100644 index 00000000..dd61bf2e --- /dev/null +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json @@ -0,0 +1,5 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.microsoftonline.com/" + } +} \ No newline at end of file diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json new file mode 100644 index 00000000..790d56ab --- /dev/null +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json @@ -0,0 +1,5 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.microsoftonline.de/" + } +} \ No newline at end of file diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json new file mode 100644 index 00000000..57c0c5cf --- /dev/null +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json @@ -0,0 +1,5 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.chinacloudapi.cn/" + } +} \ No newline at end of file diff --git a/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs b/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs index fd86a91b..b308c95a 100644 --- a/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs +++ b/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs @@ -34,7 +34,7 @@ public IActionResult Index() } // Redirects to login page to request increment consent - [AuthorizeForScopes(Scopes = new string[] { PowerBiScopes.ReadDashboard, PowerBiScopes.ReadReport, PowerBiScopes.ReadWorkspace })] + [AuthorizeForScopes(ScopeBase = new string[] { PowerBiScopes.ReadDashboard, PowerBiScopes.ReadReport, PowerBiScopes.ReadWorkspace })] public async Task Embed() { // Generate token for the signed in user diff --git a/.NET Core/Embed for your organization/UserOwnsData/appsettings.json b/.NET Core/Embed for your organization/UserOwnsData/appsettings.json index 07bac121..e03423b1 100644 --- a/.NET Core/Embed for your organization/UserOwnsData/appsettings.json +++ b/.NET Core/Embed for your organization/UserOwnsData/appsettings.json @@ -1,6 +1,6 @@ { "AzureAd": { - "Instance": "https://login.microsoftonline.com/", + "AuthorityUrl": "https://login.microsoftonline.com/", "Domain": "", "TenantId": "common", "ClientId": "", diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json new file mode 100644 index 00000000..25b8005e --- /dev/null +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json @@ -0,0 +1,6 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.microsoftonline.com/organizations/", + "ScopeBase": ["https://analysis.windows.net/powerbi/api/.default"] + } +} \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json new file mode 100644 index 00000000..1f1b178e --- /dev/null +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json @@ -0,0 +1,6 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.microsoftonline.com/organizations/", + "ScopeBase": ["https://analysis.usgovcloudapi.net/powerbi/api/.default"] + } +} \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json new file mode 100644 index 00000000..bd36cf9b --- /dev/null +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json @@ -0,0 +1,6 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.microsoftonline.de/organizations/", + "ScopeBase": ["https://analysis.cloudapi.de/powerbi/api/.default"] + } +} \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json new file mode 100644 index 00000000..cbe77fa1 --- /dev/null +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json @@ -0,0 +1,6 @@ +{ + "AzureAd": { + "AuthorityUrl": "https://login.chinacloudapi.cn/organizations/", + "ScopeBase": ["https://analysis.chinacloudapi.cn/powerbi/api/.default"] + } +} \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs index 78dc391e..b6e6961d 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs @@ -11,7 +11,7 @@ public class AzureAd public string AuthenticationMode { get; set; } // URL used for initiating authorization request - public string AuthorityUri { get; set; } + public string AuthorityUrl { get; set; } // Client Id (Application Id) of the AAD app public string ClientId { get; set; } @@ -19,8 +19,8 @@ public class AzureAd // Id of the Azure tenant in which AAD app is hosted. Required only for Service Principal authentication mode. public string TenantId { get; set; } - // Scope of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. - public string[] Scope { get; set; } + // ScopeBase of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + public string[] ScopeBase { get; set; } // Master user email address. Required only for MasterUser authentication mode. public string PbiUsername { get; set; } diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs index b58e6857..7b8f261d 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs @@ -31,12 +31,12 @@ public string GetAccessToken() if (azureAd.Value.AuthenticationMode.Equals("masteruser", StringComparison.InvariantCultureIgnoreCase)) { // Create a public client to authorize the app with the AAD app - IPublicClientApplication clientApp = PublicClientApplicationBuilder.Create(azureAd.Value.ClientId).WithAuthority(azureAd.Value.AuthorityUri).Build(); + IPublicClientApplication clientApp = PublicClientApplicationBuilder.Create(azureAd.Value.ClientId).WithAuthority(azureAd.Value.AuthorityUrl).Build(); var userAccounts = clientApp.GetAccountsAsync().Result; try { // Retrieve Access token from cache if available - authenticationResult = clientApp.AcquireTokenSilent(azureAd.Value.Scope, userAccounts.FirstOrDefault()).ExecuteAsync().Result; + authenticationResult = clientApp.AcquireTokenSilent(azureAd.Value.ScopeBase, userAccounts.FirstOrDefault()).ExecuteAsync().Result; } catch (MsalUiRequiredException) { @@ -45,7 +45,7 @@ public string GetAccessToken() { password.AppendChar(key); } - authenticationResult = clientApp.AcquireTokenByUsernamePassword(azureAd.Value.Scope, azureAd.Value.PbiUsername, password).ExecuteAsync().Result; + authenticationResult = clientApp.AcquireTokenByUsernamePassword(azureAd.Value.ScopeBase, azureAd.Value.PbiUsername, password).ExecuteAsync().Result; } } @@ -53,7 +53,7 @@ public string GetAccessToken() else { // For app only authentication, we need the specific tenant id in the authority url - var tenantSpecificUrl = azureAd.Value.AuthorityUri.Replace("organizations", azureAd.Value.TenantId); + var tenantSpecificUrl = azureAd.Value.AuthorityUrl.Replace("organizations", azureAd.Value.TenantId); // Create a confidential client to authorize the app with the AAD app IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder @@ -62,7 +62,7 @@ public string GetAccessToken() .WithAuthority(tenantSpecificUrl) .Build(); // Make a client call if Access token is not available in cache - authenticationResult = clientApp.AcquireTokenForClient(azureAd.Value.Scope).ExecuteAsync().Result; + authenticationResult = clientApp.AcquireTokenForClient(azureAd.Value.ScopeBase).ExecuteAsync().Result; } return authenticationResult.AccessToken; diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Services/ConfigValidator.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Services/ConfigValidator.cs index 1742d702..d8ac74ba 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Services/ConfigValidator.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Services/ConfigValidator.cs @@ -26,7 +26,7 @@ public static string ValidateConfig(IOptions azureAd) { message = $"Authentication mode is incorrect or {Constants.InvalidAppSetting}"; } - else if (string.IsNullOrWhiteSpace(azureAd.Value.AuthorityUri)) + else if (string.IsNullOrWhiteSpace(azureAd.Value.AuthorityUrl)) { message = $"Authority {Constants.InvalidAppSetting}"; } @@ -38,9 +38,9 @@ public static string ValidateConfig(IOptions azureAd) { message = $"Tenant Id {Constants.InvalidAppSetting}"; } - else if (azureAd.Value.Scope is null || azureAd.Value.Scope.Length == 0) + else if (azureAd.Value.ScopeBase is null || azureAd.Value.ScopeBase.Length == 0) { - message = $"Scope {Constants.InvalidAppSetting}"; + message = $"Scope base {Constants.InvalidAppSetting}"; } else if (isAuthModeMasterUser && string.IsNullOrWhiteSpace(azureAd.Value.PbiUsername)) { diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs index b87a7ea1..3f57bc3d 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs @@ -16,7 +16,7 @@ namespace EncryptCredentials.Services public class PowerBIService { private readonly AadService aadService; - private readonly string urlPowerBiServiceApiRoot = "https://api.powerbi.com"; + private readonly string powerBiApiUrl = "https://api.powerbi.com"; public PowerBIService(AadService aadService) { @@ -30,7 +30,7 @@ public PowerBIService(AadService aadService) public PowerBIClient GetPowerBIClient() { var tokenCredentials = new TokenCredentials(aadService.GetAccessToken(), "Bearer"); - return new PowerBIClient(new Uri(urlPowerBiServiceApiRoot), tokenCredentials); + return new PowerBIClient(new Uri(powerBiApiUrl), tokenCredentials); } /// diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json b/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json index 3f63e14f..4e4d0986 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json +++ b/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json @@ -1,10 +1,10 @@ { "AzureAd": { "AuthenticationMode": "ServicePrincipal", - "AuthorityUri": "https://login.microsoftonline.com/organizations/", + "AuthorityUrl": "https://login.microsoftonline.com/organizations/", "ClientId": "", "TenantId": "", - "Scope": ["https://analysis.windows.net/powerbi/api/.default"], + "ScopeBase": ["https://analysis.windows.net/powerbi/api/.default"], "RedirectUri": "http://localhost:5001/", "PbiUsername": "", "PbiPassword": "", diff --git a/.NET Framework/Embed for your customers/AppOwnsData/Services/AadService.cs b/.NET Framework/Embed for your customers/AppOwnsData/Services/AadService.cs index 9c0e210d..c5e297da 100644 --- a/.NET Framework/Embed for your customers/AppOwnsData/Services/AadService.cs +++ b/.NET Framework/Embed for your customers/AppOwnsData/Services/AadService.cs @@ -15,7 +15,7 @@ namespace AppOwnsData.Services public class AadService { private static readonly string m_authorityUrl = ConfigurationManager.AppSettings["authorityUrl"]; - private static readonly string[] m_scope = ConfigurationManager.AppSettings["scope"].Split(';'); + private static readonly string[] m_scope = ConfigurationManager.AppSettings["scopeBase"].Split(';'); /// /// Get Access token diff --git a/.NET Framework/Embed for your customers/AppOwnsData/Services/EmbedService.cs b/.NET Framework/Embed for your customers/AppOwnsData/Services/EmbedService.cs index 0006a1ad..f6352b6b 100644 --- a/.NET Framework/Embed for your customers/AppOwnsData/Services/EmbedService.cs +++ b/.NET Framework/Embed for your customers/AppOwnsData/Services/EmbedService.cs @@ -18,12 +18,12 @@ namespace AppOwnsData.Services public static class EmbedService { - private static readonly string urlPowerBiServiceApiRoot = ConfigurationManager.AppSettings["urlPowerBiServiceApiRoot"]; + private static readonly string powerBiApiUrl = ConfigurationManager.AppSettings["powerBiApiUrl"]; public static async Task GetPowerBiClient() { var tokenCredentials = new TokenCredentials(await AadService.GetAccessToken(), "Bearer"); - return new PowerBIClient(new Uri(urlPowerBiServiceApiRoot), tokenCredentials); + return new PowerBIClient(new Uri(powerBiApiUrl), tokenCredentials); } /// diff --git a/.NET Framework/Embed for your customers/AppOwnsData/Web.config b/.NET Framework/Embed for your customers/AppOwnsData/Web.config index 18b8180f..80b1d389 100644 --- a/.NET Framework/Embed for your customers/AppOwnsData/Web.config +++ b/.NET Framework/Embed for your customers/AppOwnsData/Web.config @@ -32,8 +32,8 @@ Licensed under the MIT license.--> - - + + diff --git a/.NET Framework/Embed for your organization/CloudConfigs/Power BI Global/Cloud.config b/.NET Framework/Embed for your organization/CloudConfigs/Power BI Global/Cloud.config index 856fe989..3f1a43b7 100644 --- a/.NET Framework/Embed for your organization/CloudConfigs/Power BI Global/Cloud.config +++ b/.NET Framework/Embed for your organization/CloudConfigs/Power BI Global/Cloud.config @@ -1,7 +1,7 @@  - + - + \ No newline at end of file diff --git a/.NET Framework/Embed for your organization/CloudConfigs/Power BI US Government/Cloud.config b/.NET Framework/Embed for your organization/CloudConfigs/Power BI US Government/Cloud.config index efd056d4..f9132883 100644 --- a/.NET Framework/Embed for your organization/CloudConfigs/Power BI US Government/Cloud.config +++ b/.NET Framework/Embed for your organization/CloudConfigs/Power BI US Government/Cloud.config @@ -1,7 +1,7 @@  - - + + + \ No newline at end of file diff --git a/.NET Framework/Embed for your organization/CloudConfigs/Power BI in Germany/Cloud.config b/.NET Framework/Embed for your organization/CloudConfigs/Power BI in Germany/Cloud.config index 50488477..81703bdf 100644 --- a/.NET Framework/Embed for your organization/CloudConfigs/Power BI in Germany/Cloud.config +++ b/.NET Framework/Embed for your organization/CloudConfigs/Power BI in Germany/Cloud.config @@ -1,7 +1,7 @@  - + - + \ No newline at end of file diff --git a/.NET Framework/Embed for your organization/CloudConfigs/Power BI operated by 21Vianet in China/Cloud.config b/.NET Framework/Embed for your organization/CloudConfigs/Power BI operated by 21Vianet in China/Cloud.config index e787ea8c..af00abd6 100644 --- a/.NET Framework/Embed for your organization/CloudConfigs/Power BI operated by 21Vianet in China/Cloud.config +++ b/.NET Framework/Embed for your organization/CloudConfigs/Power BI operated by 21Vianet in China/Cloud.config @@ -1,7 +1,7 @@  - + - + \ No newline at end of file diff --git a/.NET Framework/Embed for your organization/UserOwnsData/Services/ConfigValidatorService.cs b/.NET Framework/Embed for your organization/UserOwnsData/Services/ConfigValidatorService.cs index 69d54fa5..d8bdc756 100644 --- a/.NET Framework/Embed for your organization/UserOwnsData/Services/ConfigValidatorService.cs +++ b/.NET Framework/Embed for your organization/UserOwnsData/Services/ConfigValidatorService.cs @@ -33,17 +33,17 @@ public static string ValidateConfig() { message = "Redirect Uri is not set in Web.config file"; } - else if (string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["authorityUri"])) + else if (string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["authorityUrl"])) { - message = "Authority Uri is not set in Web.config file"; + message = "Authority Url is not set in Web.config file"; } else if (string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["powerBiApiUrl"])) { message = "Power BI Api Url is not set in Web.config file"; } - else if (string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["powerBiPermissionApi"])) + else if (string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["scopeBase"])) { - message = "Power BI Permission Api is not set in Web.config file"; + message = "Scope base is not set in Web.config file"; } return message; diff --git a/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/OwinOpenIdConnect.cs b/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/OwinOpenIdConnect.cs index f00dd339..0b1fc72f 100644 --- a/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/OwinOpenIdConnect.cs +++ b/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/OwinOpenIdConnect.cs @@ -19,7 +19,7 @@ namespace UserOwnsData.Services.Security public class OwinOpenIdConnect { - private static readonly string tenantCommonAuthority = ConfigurationManager.AppSettings["authorityUri"]; + private static readonly string tenantCommonAuthority = ConfigurationManager.AppSettings["authorityUrl"]; private static readonly string clientId = ConfigurationManager.AppSettings["clientId"]; private static readonly string clientSecret = ConfigurationManager.AppSettings["clientSecret"]; private static readonly string redirectUri = ConfigurationManager.AppSettings["redirectUri"]; diff --git a/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/PowerBiPermissionScopes.cs b/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/PowerBiPermissionScopes.cs index 85843b72..b45cc381 100644 --- a/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/PowerBiPermissionScopes.cs +++ b/.NET Framework/Embed for your organization/UserOwnsData/Services/Security/PowerBiPermissionScopes.cs @@ -9,12 +9,12 @@ namespace UserOwnsData.Services.Security public class PowerBIPermissionScopes { - private static readonly string powerBiPermissionApi = ConfigurationManager.AppSettings["powerBiPermissionApi"]; + private static readonly string scopeBase = ConfigurationManager.AppSettings["scopeBase"]; public static readonly string[] ReadUserWorkspaces = new string[] { - powerBiPermissionApi + "Workspace.Read.All", - powerBiPermissionApi + "Report.Read.All", - powerBiPermissionApi + "Dashboard.Read.All" + scopeBase + "Workspace.Read.All", + scopeBase + "Report.Read.All", + scopeBase + "Dashboard.Read.All" }; } } diff --git a/.NET Framework/Embed for your organization/UserOwnsData/Web.config b/.NET Framework/Embed for your organization/UserOwnsData/Web.config index f51e7eeb..e763338c 100644 --- a/.NET Framework/Embed for your organization/UserOwnsData/Web.config +++ b/.NET Framework/Embed for your organization/UserOwnsData/Web.config @@ -6,9 +6,9 @@ - + - + diff --git a/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/config/Config.java b/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/config/Config.java index 2fe80603..d66133cc 100644 --- a/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/config/Config.java +++ b/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/config/Config.java @@ -39,7 +39,7 @@ public abstract class Config { // DO NOT CHANGE public static final String authorityUrl = "https://login.microsoftonline.com/"; - public static final String scopeUrl = "https://analysis.windows.net/powerbi/api/.default"; + public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; private Config(){ diff --git a/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/services/AzureADService.java b/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/services/AzureADService.java index dd5a06ea..5bb33cd2 100644 --- a/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/services/AzureADService.java +++ b/Java/Embed for your customers/AppOwnsData/src/main/java/com/embedsample/appownsdata/services/AzureADService.java @@ -70,7 +70,7 @@ private static String getAccessTokenUsingServicePrincipal(String clientId, Strin .build(); ClientCredentialParameters clientCreds = ClientCredentialParameters.builder( - Collections.singleton(Config.scopeUrl)) + Collections.singleton(Config.scopeBase)) .build(); // Acquire new AAD token @@ -103,7 +103,7 @@ private static String getAccessTokenUsingMasterUser(String clientId, String user .build(); UserNamePasswordParameters userCreds = UserNamePasswordParameters.builder( - Collections.singleton(Config.scopeUrl), + Collections.singleton(Config.scopeBase), username, password.toCharArray()).build(); diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java new file mode 100644 index 00000000..7b60a136 --- /dev/null +++ b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java @@ -0,0 +1,12 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +//Replace these configs with the one in the Config.java file for sovereign cloud + +public abstract class Config { + + public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; +} \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java new file mode 100644 index 00000000..34d06419 --- /dev/null +++ b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java @@ -0,0 +1,12 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +//Replace these configs with the one in the Config.java file for sovereign cloud + +public abstract class Config { + + public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String scopeBase = "https://analysis.usgovcloudapi.net/powerbi/api/.default"; +} \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java new file mode 100644 index 00000000..be256039 --- /dev/null +++ b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java @@ -0,0 +1,12 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +//Replace these configs with the one in the Config.java file for sovereign cloud + +public abstract class Config { + + public static final String authorityUrl = "https://login.microsoftonline.de/"; + public static final String scopeBase = "https://analysis.cloudapi.de/powerbi/api/.default"; +} \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java new file mode 100644 index 00000000..1b288fef --- /dev/null +++ b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java @@ -0,0 +1,12 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +//Replace these configs with the one in the Config.java file for sovereign cloud + +public abstract class Config { + + public static final String authorityUrl = "https://login.chinacloudapi.cn/"; + public static final String scopeBase = "https://analysis.chinacloudapi.cn/powerbi/api/.default"; +} \ No newline at end of file diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java index 3ec6fa42..310e3996 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java @@ -35,7 +35,7 @@ public abstract class Config { // DO NOT CHANGE public static final String authorityUrl = "https://login.microsoftonline.com/"; - public static final String scopeUrl = "https://analysis.windows.net/powerbi/api/.default"; + public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; private Config() { // Private Constructor will prevent the instantiation of this class directly diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AzureADService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AzureADService.java index bddd9e87..b5e7d9f5 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AzureADService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AzureADService.java @@ -73,7 +73,7 @@ private static String getAccessTokenUsingServicePrincipal(String clientId, Strin .authority(Config.authorityUrl + tenantId).build(); ClientCredentialParameters clientCreds = ClientCredentialParameters - .builder(Collections.singleton(Config.scopeUrl)).build(); + .builder(Collections.singleton(Config.scopeBase)).build(); // Acquire new AAD token IAuthenticationResult result = app.acquireToken(clientCreds).get(); @@ -109,7 +109,7 @@ private static String getAccessTokenUsingMasterUser(String clientId, String user .build(); UserNamePasswordParameters userCreds = UserNamePasswordParameters - .builder(Collections.singleton(Config.scopeUrl), username, password.toCharArray()).build(); + .builder(Collections.singleton(Config.scopeBase), username, password.toCharArray()).build(); // Acquire new AAD token IAuthenticationResult result = app.acquireToken(userCreds).get(); diff --git a/NodeJS/Embed for your customers/AppOwnsData/config/config.json b/NodeJS/Embed for your customers/AppOwnsData/config/config.json index c6e2f221..658a6954 100644 --- a/NodeJS/Embed for your customers/AppOwnsData/config/config.json +++ b/NodeJS/Embed for your customers/AppOwnsData/config/config.json @@ -1,8 +1,8 @@ { "authenticationMode": "MasterUser", - "authorityUri": "https://login.microsoftonline.com/common/v2.0", - "scope": "https://analysis.windows.net/powerbi/api", - "apiUrl": "https://api.powerbi.com/", + "authorityUrl": "https://login.microsoftonline.com/common/v2.0", + "scopeBase": "https://analysis.windows.net/powerbi/api", + "powerBiApiUrl": "https://api.powerbi.com/", "clientId": "", "workspaceId": "", "reportId": "", diff --git a/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js b/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js index 1480b99b..771d3c05 100644 --- a/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js +++ b/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js @@ -13,7 +13,7 @@ const getAccessToken = async function () { // Create a config variable that store credentials from config.json let config = require(__dirname + "/../config/config.json"); - let authorityUrl = config.authorityUri; + let authorityUrl = config.authorityUrl; // Check for the MasterUser Authentication if (config.authenticationMode.toLowerCase() === "masteruser") { @@ -21,7 +21,7 @@ const getAccessToken = async function () { return new Promise( (resolve, reject) => { - context.acquireTokenWithUsernamePassword(config.scope, config.pbiUsername, config.pbiPassword, config.clientId, function (err, tokenResponse) { + context.acquireTokenWithUsernamePassword(config.scopeBase, config.pbiUsername, config.pbiPassword, config.clientId, function (err, tokenResponse) { // Function returns error object in tokenResponse // Invalid Username will return empty tokenResponse, thus err is used @@ -40,7 +40,7 @@ const getAccessToken = async function () { return new Promise( (resolve, reject) => { - context.acquireTokenWithClientCredentials(config.scope, config.clientId, config.clientSecret, function (err, tokenResponse) { + context.acquireTokenWithClientCredentials(config.scopeBase, config.clientId, config.clientSecret, function (err, tokenResponse) { // Function returns error object in tokenResponse // Invalid Username will return empty tokenResponse, thus err is used diff --git a/NodeJS/Embed for your customers/AppOwnsData/src/utils.js b/NodeJS/Embed for your customers/AppOwnsData/src/utils.js index a1a7a381..b3f045bc 100644 --- a/NodeJS/Embed for your customers/AppOwnsData/src/utils.js +++ b/NodeJS/Embed for your customers/AppOwnsData/src/utils.js @@ -49,8 +49,8 @@ function validateConfig() { return "WorkspaceId must be a Guid object. Please select a workspace you own and fill its Id in config.json."; } - if (!config.authorityUri) { - return "AuthorityUri is empty. Please fill valid AuthorityUri in config.json."; + if (!config.authorityUrl) { + return "AuthorityUrl is empty. Please fill valid AuthorityUrl in config.json."; } if (config.authenticationMode.toLowerCase() === "masteruser") { diff --git a/Python/Embed for your customers/AppOwnsData/config.py b/Python/Embed for your customers/AppOwnsData/config.py index 80fef337..bb10a2c5 100644 --- a/Python/Embed for your customers/AppOwnsData/config.py +++ b/Python/Embed for your customers/AppOwnsData/config.py @@ -21,11 +21,11 @@ class BaseConfig(object): # Client Secret (App Secret) of the AAD app. Required only for ServicePrincipal authentication mode. CLIENT_SECRET = '' - # Scope of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. - SCOPE = ['https://analysis.windows.net/powerbi/api/.default'] + # Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + SCOPE_BASE = ['https://analysis.windows.net/powerbi/api/.default'] # URL used for initiating authorization request - AUTHORITY = 'https://login.microsoftonline.com/organizations' + AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' # Master user email address. Required only for MasterUser authentication mode. POWER_BI_USER = '' diff --git a/Python/Embed for your customers/AppOwnsData/services/aadservice.py b/Python/Embed for your customers/AppOwnsData/services/aadservice.py index e8cdc96e..9ec780ea 100644 --- a/Python/Embed for your customers/AppOwnsData/services/aadservice.py +++ b/Python/Embed for your customers/AppOwnsData/services/aadservice.py @@ -18,24 +18,24 @@ def get_access_token(): if app.config['AUTHENTICATION_MODE'].lower() == 'masteruser': # Create a public client to authorize the app with the AAD app - clientapp = msal.PublicClientApplication(app.config['CLIENT_ID'], authority=app.config['AUTHORITY']) + clientapp = msal.PublicClientApplication(app.config['CLIENT_ID'], authority=app.config['AUTHORITY_URL']) accounts = clientapp.get_accounts(username=app.config['POWER_BI_USER']) if accounts: # Retrieve Access token from user cache if available - response = clientapp.acquire_token_silent(app.config['SCOPE'], account=accounts[0]) + response = clientapp.acquire_token_silent(app.config['SCOPE_BASE'], account=accounts[0]) if not response: # Make a client call if Access token is not available in cache - response = clientapp.acquire_token_by_username_password(app.config['POWER_BI_USER'], app.config['POWER_BI_PASS'], scopes=app.config['SCOPE']) + response = clientapp.acquire_token_by_username_password(app.config['POWER_BI_USER'], app.config['POWER_BI_PASS'], scopes=app.config['SCOPE_BASE']) # Service Principal auth is the recommended by Microsoft to achieve App Owns Data Power BI embedding elif app.config['AUTHENTICATION_MODE'].lower() == 'serviceprincipal': - authority = app.config['AUTHORITY'].replace('organizations', app.config['TENANT_ID']) + authority = app.config['AUTHORITY_URL'].replace('organizations', app.config['TENANT_ID']) clientapp = msal.ConfidentialClientApplication(app.config['CLIENT_ID'], client_credential=app.config['CLIENT_SECRET'], authority=authority) # Make a client call if Access token is not available in cache - response = clientapp.acquire_token_for_client(scopes=app.config['SCOPE']) + response = clientapp.acquire_token_for_client(scopes=app.config['SCOPE_BASE']) try: return response['access_token'] diff --git a/Python/Embed for your customers/AppOwnsData/utils.py b/Python/Embed for your customers/AppOwnsData/utils.py index 5ba88c65..22b71a24 100644 --- a/Python/Embed for your customers/AppOwnsData/utils.py +++ b/Python/Embed for your customers/AppOwnsData/utils.py @@ -31,8 +31,8 @@ def check_config(app): elif app.config['AUTHENTICATION_MODE'].lower() == 'serviceprincipal': if app.config['CLIENT_SECRET'] == '': return 'Client secret is not provided in config.py file' - elif app.config['SCOPE'] == '': - return 'Scope is not provided in the config.py file' + elif app.config['SCOPE_BASE'] == '': + return 'Scope base is not provided in the config.py file' elif app.config['AUTHORITY_URL'] == '': return 'Authority URL is not provided in the config.py file' diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py new file mode 100644 index 00000000..3ec60b18 --- /dev/null +++ b/Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py @@ -0,0 +1,12 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +# Replace these configs with the one in the config.py file for sovereign cloud + +class BaseConfig(object): + + # Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + SCOPE_BASE = ['https://analysis.windows.net/powerbi/api/.default'] + + # URL used for initiating authorization request + AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' \ No newline at end of file diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py new file mode 100644 index 00000000..67d42356 --- /dev/null +++ b/Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py @@ -0,0 +1,12 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +# Replace these configs with the one in the config.py file for sovereign cloud + +class BaseConfig(object): + + # Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + SCOPE_BASE = ['https://analysis.usgovcloudapi.net/powerbi/api/.default'] + + # URL used for initiating authorization request + AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' \ No newline at end of file diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py new file mode 100644 index 00000000..cd9b414a --- /dev/null +++ b/Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py @@ -0,0 +1,12 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +# Replace these configs with the one in the config.py file for sovereign cloud + +class BaseConfig(object): + + # Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + SCOPE_BASE = ['https://analysis.cloudapi.de/powerbi/api/.default'] + + # URL used for initiating authorization request + AUTHORITY_URL = 'https://login.microsoftonline.de/organizations' \ No newline at end of file diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py new file mode 100644 index 00000000..d775bfb8 --- /dev/null +++ b/Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py @@ -0,0 +1,12 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +# Replace these configs with the one in the config.py file for sovereign cloud + +class BaseConfig(object): + + # Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + SCOPE_BASE = ['https://analysis.chinacloudapi.cn/powerbi/api/.default'] + + # URL used for initiating authorization request + AUTHORITY_URL = 'https://login.chinacloudapi.cn/organizations' \ No newline at end of file diff --git a/Python/Encrypt credentials/Encryption sample/config.py b/Python/Encrypt credentials/Encryption sample/config.py index 48f45482..7d20eac1 100644 --- a/Python/Encrypt credentials/Encryption sample/config.py +++ b/Python/Encrypt credentials/Encryption sample/config.py @@ -15,11 +15,11 @@ class BaseConfig(object): # Client Secret (App Secret) of the AAD app. Required only for ServicePrincipal authentication mode. CLIENT_SECRET = '' - # Scope of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. - SCOPE = ['https://analysis.windows.net/powerbi/api/.default'] + # Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. + SCOPE_BASE = ['https://analysis.windows.net/powerbi/api/.default'] # URL used for initiating authorization request - AUTHORITY = 'https://login.microsoftonline.com/organizations' + AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' # Master user email address. Required only for MasterUser authentication mode. POWER_BI_USER = '' diff --git a/Python/Encrypt credentials/Encryption sample/services/aadservice.py b/Python/Encrypt credentials/Encryption sample/services/aadservice.py index d98a0275..c2f27340 100644 --- a/Python/Encrypt credentials/Encryption sample/services/aadservice.py +++ b/Python/Encrypt credentials/Encryption sample/services/aadservice.py @@ -25,8 +25,8 @@ def get_access_token(): username = app.config['POWER_BI_USER'] password = app.config['POWER_BI_PASS'] client_secret = app.config['CLIENT_SECRET'] - scope = app.config['SCOPE'] - authority = app.config['AUTHORITY'] + scope = app.config['SCOPE_BASE'] + authority = app.config['AUTHORITY_URL'] response = None try: diff --git a/Python/Encrypt credentials/Encryption sample/utils.py b/Python/Encrypt credentials/Encryption sample/utils.py index fa2e3d61..7ecb0ae1 100644 --- a/Python/Encrypt credentials/Encryption sample/utils.py +++ b/Python/Encrypt credentials/Encryption sample/utils.py @@ -27,8 +27,8 @@ def validate_config(app): username = app.config['POWER_BI_USER'] password = app.config['POWER_BI_PASS'] client_secret = app.config['CLIENT_SECRET'] - scope = app.config['SCOPE'] - authority = app.config['AUTHORITY'] + scope = app.config['SCOPE_BASE'] + authority = app.config['AUTHORITY_URL'] if authenticate_mode == '': return 'Please specify one of the two authentication modes in config.py file' @@ -46,7 +46,7 @@ def validate_config(app): if authenticate_mode.lower() == 'serviceprincipal' and client_secret == '': return 'Client secret is not provided in config.py file' if scope == '': - return 'Scope is not provided in config.py file' + return 'Scope base is not provided in config.py file' if authority == '': return 'Authority URL is not provided in config.py file' diff --git a/React-TS/CloudConfigs/Power BI Global/Config.ts b/React-TS/CloudConfigs/Power BI Global/Config.ts new file mode 100644 index 00000000..57537242 --- /dev/null +++ b/React-TS/CloudConfigs/Power BI Global/Config.ts @@ -0,0 +1,10 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +// Refer https://aka.ms/PowerBIPermissions for complete list of Power BI scopes + +// Replace this config with the one in the Config.ts file for sovereign cloud + +export const scopeBase: string[] = ["https://analysis.windows.net/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/CloudConfigs/Power BI US Government/Config.ts b/React-TS/CloudConfigs/Power BI US Government/Config.ts new file mode 100644 index 00000000..4902dcb4 --- /dev/null +++ b/React-TS/CloudConfigs/Power BI US Government/Config.ts @@ -0,0 +1,10 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +// Refer https://aka.ms/PowerBIPermissions for complete list of Power BI scopes + +// Replace this config with the one in the Config.ts file for sovereign cloud + +export const scopeBase: string[] = ["https://analysis.usgovcloudapi.net/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/CloudConfigs/Power BI in Germany/Config.ts b/React-TS/CloudConfigs/Power BI in Germany/Config.ts new file mode 100644 index 00000000..3ba38d7e --- /dev/null +++ b/React-TS/CloudConfigs/Power BI in Germany/Config.ts @@ -0,0 +1,10 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +// Refer https://aka.ms/PowerBIPermissions for complete list of Power BI scopes + +// Replace this config with the one in the Config.ts file for sovereign cloud + +export const scopeBase: string[] = ["https://analysis.cloudapi.de/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts b/React-TS/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts new file mode 100644 index 00000000..cfa23ea8 --- /dev/null +++ b/React-TS/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts @@ -0,0 +1,10 @@ +// ---------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// ---------------------------------------------------------------------------- + +// Refer https://aka.ms/PowerBIPermissions for complete list of Power BI scopes + +// Replace this config with the one in the Config.ts file for sovereign cloud + +export const scopeBase: string[] = ["https://analysis.chinacloudapi.cn/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/Embed for your organization/UserOwnsData/src/App.tsx b/React-TS/Embed for your organization/UserOwnsData/src/App.tsx index 3d4bfd03..e3512352 100644 --- a/React-TS/Embed for your organization/UserOwnsData/src/App.tsx +++ b/React-TS/Embed for your organization/UserOwnsData/src/App.tsx @@ -134,7 +134,7 @@ class App extends React.Component { }; const loginRequest = { - scopes: config.scopes + scopes: config.scopeBase }; const msalInstance: UserAgentApplication = new UserAgentApplication(msalConfig); diff --git a/React-TS/Embed for your organization/UserOwnsData/src/Config.ts b/React-TS/Embed for your organization/UserOwnsData/src/Config.ts index e3f5a2b7..fc99a0d4 100644 --- a/React-TS/Embed for your organization/UserOwnsData/src/Config.ts +++ b/React-TS/Embed for your organization/UserOwnsData/src/Config.ts @@ -5,9 +5,9 @@ /* eslint-disable @typescript-eslint/no-inferrable-types */ -// Scope of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. +// Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. // Refer https://aka.ms/PowerBIPermissions for complete list of Power BI scopes -export const scopes: string[] = ["https://analysis.windows.net/powerbi/api/Report.Read.All"]; +export const scopeBase: string[] = ["https://analysis.windows.net/powerbi/api/Report.Read.All"]; // Client Id (Application Id) of the AAD app. export const clientId: string = ""; From e89e8c51a6c8a5396cee928e9e1e67247fa396b4 Mon Sep 17 00:00:00 2001 From: "Atharva Bapat(MAQ LLC)" Date: Tue, 22 Feb 2022 17:36:09 +0530 Subject: [PATCH 2/8] updated reference in Java samples --- .../CloudConfigs/Power BI Global/Config.java | 1 + .../CloudConfigs/Power BI US Government/Config.java | 1 + .../CloudConfigs/Power BI in Germany/Config.java | 1 + .../Power BI operated by 21Vianet in China/Config.java | 1 + .../encryptcredential/config/Config.java | 1 + .../encryptcredential/services/AddCredentialsService.java | 3 ++- .../encryptcredential/services/GetDatasourceData.java | 5 +++-- .../encryptcredential/services/UpdateCredentialsService.java | 3 ++- 8 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java index 7b60a136..2a8ae387 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String powerBiApiUrl = "https://api.powerbi.com/"; public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java index 34d06419..f50dc40d 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String powerBiApiUrl = "https://api.powerbigov.us/"; public static final String scopeBase = "https://analysis.usgovcloudapi.net/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java index be256039..af7f8b30 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.de/"; + public static final String powerBiApiUrl = "https://api.powerbi.de/"; public static final String scopeBase = "https://analysis.cloudapi.de/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java index 1b288fef..80606c61 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.chinacloudapi.cn/"; + public static final String powerBiApiUrl = "https://api.powerbi.cn/"; public static final String scopeBase = "https://analysis.chinacloudapi.cn/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java index 310e3996..f6ba6c24 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java @@ -35,6 +35,7 @@ public abstract class Config { // DO NOT CHANGE public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String powerBiApiUrl = "https://api.powerbi.com/"; public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; private Config() { diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java index df09c28d..621a3318 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java @@ -13,6 +13,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; +import com.embedsample.appownsdata.config.Config; import com.encryptcredentialsample.encryptcredential.models.CredentialDetails; import com.encryptcredentialsample.encryptcredential.models.GatewayPublicKey; import com.encryptcredentialsample.encryptcredential.models.PublishDatasourceToGatewayRequest; @@ -49,7 +50,7 @@ public static ResponseEntity addDataSource( public static ResponseEntity makeAddDataSourcePostRequest(String gatewayId, PublishDatasourceToGatewayRequest requestBody, String accessToken) throws ClientProtocolException, IOException { // Gateways - Create Datasource Power BI REST API // https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/createdatasource - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + gatewayId + "/datasources"; + String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/gateways/" + gatewayId + "/datasources"; // Request header HttpHeaders reqHeader = Utils.generateAuthorizationHeaders(accessToken); diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java index fefafefe..c5b97fc2 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java @@ -13,6 +13,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; +import com.embedsample.appownsdata.config.Config; import com.encryptcredentialsample.encryptcredential.models.Gateway; import com.encryptcredentialsample.encryptcredential.models.GetDatasourcesResponse; @@ -21,7 +22,7 @@ public class GetDatasourceData { public static Gateway getGateway(String accessToken, String getwayId) { // REST API URL to get data sources - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + getwayId; + String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/gateways/" + getwayId; // Request header HttpHeaders reqHeader = new HttpHeaders(); @@ -49,7 +50,7 @@ public static GetDatasourcesResponse getDatasourcesInGroup(String accessToken, S HttpEntity reqEntity = new HttpEntity<>(reqHeader); // https://docs.microsoft.com/en-us/rest/api/power-bi/datasets/getdatasourcesingroup - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/groups/" + groupId + "/datasets/" + datasetId + "/datasources"; + String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/groups/" + groupId + "/datasets/" + datasetId + "/datasources"; // Rest API get datasources's details RestTemplate getDatasourceRestTemplate = new RestTemplate(); diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java index ec0f10e0..0a2de5ee 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java @@ -14,6 +14,7 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; +import com.embedsample.appownsdata.config.Config; import com.encryptcredentialsample.encryptcredential.models.CredentialDetails; import com.encryptcredentialsample.encryptcredential.models.CredentialDetailsRequestBody; import com.encryptcredentialsample.encryptcredential.models.Gateway; @@ -70,7 +71,7 @@ public static ResponseEntity makeUpdateDataSourcePatchRequest( // Gateways - Update Datasource Power BI REST API // https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/updatedatasource - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + gatewayId + "/datasources/" + datasourceId; + String endPointUrl =Config.powerBiApiUrl + "v1.0/myorg/gateways/" + gatewayId + "/datasources/" + datasourceId; // Request header HttpHeaders reqHeader = Utils.generateAuthorizationHeaders(accessToken); From 165a78b7ad06ed82fc3dad19bc4918877144bea0 Mon Sep 17 00:00:00 2001 From: "Atharva Bapat(MAQ LLC)" Date: Wed, 23 Feb 2022 10:24:03 +0530 Subject: [PATCH 3/8] undo previous commit --- .../CloudConfigs/Power BI Global/Config.java | 1 - .../CloudConfigs/Power BI US Government/Config.java | 1 - .../CloudConfigs/Power BI in Germany/Config.java | 1 - .../Power BI operated by 21Vianet in China/Config.java | 1 - .../encryptcredential/config/Config.java | 1 - .../encryptcredential/services/AddCredentialsService.java | 3 +-- .../encryptcredential/services/GetDatasourceData.java | 5 ++--- .../encryptcredential/services/UpdateCredentialsService.java | 3 +-- 8 files changed, 4 insertions(+), 12 deletions(-) diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java index 2a8ae387..7b60a136 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java @@ -8,6 +8,5 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.com/"; - public static final String powerBiApiUrl = "https://api.powerbi.com/"; public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java index f50dc40d..34d06419 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java @@ -8,6 +8,5 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.com/"; - public static final String powerBiApiUrl = "https://api.powerbigov.us/"; public static final String scopeBase = "https://analysis.usgovcloudapi.net/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java index af7f8b30..be256039 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java @@ -8,6 +8,5 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.de/"; - public static final String powerBiApiUrl = "https://api.powerbi.de/"; public static final String scopeBase = "https://analysis.cloudapi.de/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java index 80606c61..1b288fef 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java @@ -8,6 +8,5 @@ public abstract class Config { public static final String authorityUrl = "https://login.chinacloudapi.cn/"; - public static final String powerBiApiUrl = "https://api.powerbi.cn/"; public static final String scopeBase = "https://analysis.chinacloudapi.cn/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java index f6ba6c24..310e3996 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java @@ -35,7 +35,6 @@ public abstract class Config { // DO NOT CHANGE public static final String authorityUrl = "https://login.microsoftonline.com/"; - public static final String powerBiApiUrl = "https://api.powerbi.com/"; public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; private Config() { diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java index 621a3318..df09c28d 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java @@ -13,7 +13,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; -import com.embedsample.appownsdata.config.Config; import com.encryptcredentialsample.encryptcredential.models.CredentialDetails; import com.encryptcredentialsample.encryptcredential.models.GatewayPublicKey; import com.encryptcredentialsample.encryptcredential.models.PublishDatasourceToGatewayRequest; @@ -50,7 +49,7 @@ public static ResponseEntity addDataSource( public static ResponseEntity makeAddDataSourcePostRequest(String gatewayId, PublishDatasourceToGatewayRequest requestBody, String accessToken) throws ClientProtocolException, IOException { // Gateways - Create Datasource Power BI REST API // https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/createdatasource - String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/gateways/" + gatewayId + "/datasources"; + String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + gatewayId + "/datasources"; // Request header HttpHeaders reqHeader = Utils.generateAuthorizationHeaders(accessToken); diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java index c5b97fc2..fefafefe 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java @@ -13,7 +13,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; -import com.embedsample.appownsdata.config.Config; import com.encryptcredentialsample.encryptcredential.models.Gateway; import com.encryptcredentialsample.encryptcredential.models.GetDatasourcesResponse; @@ -22,7 +21,7 @@ public class GetDatasourceData { public static Gateway getGateway(String accessToken, String getwayId) { // REST API URL to get data sources - String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/gateways/" + getwayId; + String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + getwayId; // Request header HttpHeaders reqHeader = new HttpHeaders(); @@ -50,7 +49,7 @@ public static GetDatasourcesResponse getDatasourcesInGroup(String accessToken, S HttpEntity reqEntity = new HttpEntity<>(reqHeader); // https://docs.microsoft.com/en-us/rest/api/power-bi/datasets/getdatasourcesingroup - String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/groups/" + groupId + "/datasets/" + datasetId + "/datasources"; + String endPointUrl = "https://api.powerbi.com/v1.0/myorg/groups/" + groupId + "/datasets/" + datasetId + "/datasources"; // Rest API get datasources's details RestTemplate getDatasourceRestTemplate = new RestTemplate(); diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java index 0a2de5ee..ec0f10e0 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java @@ -14,7 +14,6 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; -import com.embedsample.appownsdata.config.Config; import com.encryptcredentialsample.encryptcredential.models.CredentialDetails; import com.encryptcredentialsample.encryptcredential.models.CredentialDetailsRequestBody; import com.encryptcredentialsample.encryptcredential.models.Gateway; @@ -71,7 +70,7 @@ public static ResponseEntity makeUpdateDataSourcePatchRequest( // Gateways - Update Datasource Power BI REST API // https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/updatedatasource - String endPointUrl =Config.powerBiApiUrl + "v1.0/myorg/gateways/" + gatewayId + "/datasources/" + datasourceId; + String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + gatewayId + "/datasources/" + datasourceId; // Request header HttpHeaders reqHeader = Utils.generateAuthorizationHeaders(accessToken); From 0d36b89f4ab10625cb14f3c4d2476707e16721fd Mon Sep 17 00:00:00 2001 From: Atharva Bapat Date: Wed, 9 Mar 2022 10:18:47 +0000 Subject: [PATCH 4/8] Merged PR 243931: [Developer Samples]: Add try catch block for encryption samples Here we handle the case when we have cloud gateway. In case of cloud gateway, when we try to get the gateway information using `gatewayId`, the call throws a `404 Not Found` error. This error indicates the existence of cloud gateway. In case of on-premises gateway, we get a success response with information like `publicKey`(required for encryption). So here, we add try catch block to handle the `404` error and continue the flow with cloud gateway. --- .../Services/PowerBIService.cs | 13 ++++++++++++- .../controllers/DataSourceController.java | 3 --- .../services/UpdateCredentialsService.java | 17 ++++++++++++----- .../Encryption sample/app.py | 11 ++++++++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs index 3f57bc3d..3b5ae1c1 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs @@ -110,7 +110,18 @@ public CredentialDetails GetCredentialDetails(Guid gatewayId, string credentialT var credentials = GetCredentials(credentialType, credentialsArray); // Get the Getway - var gateway = GetGateway(gatewayId); + Gateway gateway = new Gateway(gatewayId); + try + { + gateway = GetGateway(gatewayId); + } + catch (HttpOperationException e) + { + if (e.Response.ReasonPhrase != "Not Found") + { + throw; + } + } // Initialize credentialsEncryptor and encryptedConnection for Cloud gateway var credentialsEncryptor = (AsymmetricKeyEncryptor)null; diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/controllers/DataSourceController.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/controllers/DataSourceController.java index 2f92ce53..ea05ccc6 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/controllers/DataSourceController.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/controllers/DataSourceController.java @@ -94,14 +94,11 @@ public ResponseEntity updateDataController(@RequestBody UpdateDatasourceCrede // Get access token and Update Datasource Credentials String accessToken = AzureADService.getAccessToken(); - Gateway gateway = GetDatasourceData.getGateway(accessToken, request.gatewayId); - return UpdateCredentialsService.updateDatasource( accessToken, request.credType, request.privacyLevel, request.credentialsArray, - gateway.publicKey, request.gatewayId, request.datasourceId); } catch (HttpClientErrorException hcex) { diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java index ec0f10e0..1bde2b5d 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java @@ -12,12 +12,12 @@ import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import com.encryptcredentialsample.encryptcredential.models.CredentialDetails; import com.encryptcredentialsample.encryptcredential.models.CredentialDetailsRequestBody; import com.encryptcredentialsample.encryptcredential.models.Gateway; -import com.encryptcredentialsample.encryptcredential.models.GatewayPublicKey; public class UpdateCredentialsService { @@ -27,7 +27,6 @@ public static ResponseEntity updateDatasource( String credType, String privacyLevel, String[] credentialsArray, - GatewayPublicKey pubKey, String gatewayId, String datasourceId) throws Exception { @@ -35,16 +34,24 @@ public static ResponseEntity updateDatasource( String serializedCredentials = Utils.serializeCredentials(credentialsArray, credType); String encryptedCredentialsString = null; - - Gateway gateway = GetDatasourceData.getGateway(accessToken, gatewayId); String encryptedConnection = null; + + Gateway gateway = new Gateway(); + try { + gateway = GetDatasourceData.getGateway(accessToken, gatewayId); + } + catch (HttpClientErrorException e) { + if (!e.getStatusText().toString().equals("Not Found")) { + throw e; + } + } // On-premises gateway contains name property // Use on-premises gateway if (gateway.name != null) { encryptedConnection = "Encrypted"; // Encrypt the credentials Asymmetric Key Encryption - AsymmetricKeyEncryptorService credentialsEncryptor = new AsymmetricKeyEncryptorService(pubKey); + AsymmetricKeyEncryptorService credentialsEncryptor = new AsymmetricKeyEncryptorService(gateway.publicKey); encryptedCredentialsString = credentialsEncryptor.encodeCredentials(serializedCredentials); } else { // Use cloud gateway diff --git a/Python/Encrypt credentials/Encryption sample/app.py b/Python/Encrypt credentials/Encryption sample/app.py index b58c4a58..1830ea02 100644 --- a/Python/Encrypt credentials/Encryption sample/app.py +++ b/Python/Encrypt credentials/Encryption sample/app.py @@ -59,6 +59,10 @@ def update_datasource(): request_data = request.json['data'] gateway_id = request_data['gatewayId'] + gateway = { + 'id': gateway_id, + 'publicKey': None, + } # Validate the credentials data by the user data_validation_service = DataValidationService() @@ -68,9 +72,10 @@ def update_datasource(): gateway_api_response = data_source_service.get_gateway(access_token, gateway_id) if not gateway_api_response.ok: - return json.dumps({'errorMsg' : str(f'Error {gateway_api_response.status_code} {gateway_api_response.reason}\nRequest Id:\t{gateway_api_response.headers.get("RequestId")}')}), gateway_api_response.status_code - - gateway = gateway_api_response.json() + if not gateway_api_response.reason == "Not Found": + return json.dumps({'errorMsg' : str(f'Error {gateway_api_response.status_code} {gateway_api_response.reason}\nRequest Id:\t{gateway_api_response.headers.get("RequestId")}')}), gateway_api_response.status_code + else: + gateway = gateway_api_response.json() # Send fetched data to update credentials update_creds_service = UpdateCredentialsService() From c25608d0871c21a240ada92aa9ba5aeb7f9ade55 Mon Sep 17 00:00:00 2001 From: Atharva Bapat Date: Tue, 29 Mar 2022 06:15:14 +0000 Subject: [PATCH 5/8] Merged PR 239856: [Developer Samples]: Update reference to environment variables Related work items: #766862, #769896 --- .../Power BI Global/appsettings.json | 3 ++- .../Power BI US Government/appsettings.json | 3 ++- .../Power BI in Germany/appsettings.json | 3 ++- .../appsettings.json | 3 ++- .../UserOwnsData/Controllers/HomeController.cs | 12 ++++++++---- .../UserOwnsData/Service/PowerBiScopes.cs | 14 -------------- .../UserOwnsData/Startup.cs | 2 +- .../UserOwnsData/appsettings.json | 2 ++ .../Power BI Global/appsettings.json | 1 + .../Power BI US Government/appsettings.json | 1 + .../Power BI in Germany/appsettings.json | 1 + .../appsettings.json | 1 + .../EncryptCredentials/Models/AzureAd.cs | 3 +++ .../EncryptCredentials/Services/AadService.cs | 4 ++++ .../EncryptCredentials/Services/PowerBIService.cs | 3 +-- .../EncryptCredentials/appsettings.json | 1 + .../CloudConfigs/Power BI Global/Config.java | 1 + .../Power BI US Government/Config.java | 1 + .../CloudConfigs/Power BI in Germany/Config.java | 1 + .../Config.java | 1 + .../encryptcredential/config/Config.java | 1 + .../services/AddCredentialsService.java | 3 ++- .../services/GetDatasourceData.java | 7 ++++--- .../services/UpdateCredentialsService.java | 3 ++- .../CloudConfigs/Power BI Global/config.py | 5 ++++- .../CloudConfigs/Power BI US Government/config.py | 5 ++++- .../CloudConfigs/Power BI in Germany/config.py | 5 ++++- .../config.py | 5 ++++- .../Encryption sample/config.py | 3 +++ .../services/addcredentialsservice.py | 3 ++- .../Encryption sample/services/getdatasource.py | 6 +++--- .../services/updatecredentialsservice.py | 3 ++- 32 files changed, 71 insertions(+), 39 deletions(-) delete mode 100644 .NET Core/Embed for your organization/UserOwnsData/Service/PowerBiScopes.cs diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json index dd61bf2e..fb698f9c 100644 --- a/.NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI Global/appsettings.json @@ -1,5 +1,6 @@ { "AzureAd": { - "AuthorityUrl": "https://login.microsoftonline.com/" + "AuthorityUrl": "https://login.microsoftonline.com/", + "Scopes": ["https://analysis.windows.net/powerbi/api/Report.Read.All https://analysis.windows.net/powerbi/api/Dashboard.Read.All https://analysis.windows.net/powerbi/api/Workspace.Read.All"] } } \ No newline at end of file diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json index dd61bf2e..b46bf6d4 100644 --- a/.NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI US Government/appsettings.json @@ -1,5 +1,6 @@ { "AzureAd": { - "AuthorityUrl": "https://login.microsoftonline.com/" + "AuthorityUrl": "https://login.microsoftonline.com/", + "Scopes": ["https://analysis.usgovcloudapi.net/powerbi/api/Report.Read.All https://analysis.usgovcloudapi.net/powerbi/api/Dashboard.Read.All https://analysis.usgovcloudapi.net/powerbi/api/Workspace.Read.All"] } } \ No newline at end of file diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json index 790d56ab..25cfb091 100644 --- a/.NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI in Germany/appsettings.json @@ -1,5 +1,6 @@ { "AzureAd": { - "AuthorityUrl": "https://login.microsoftonline.de/" + "AuthorityUrl": "https://login.microsoftonline.de/", + "Scopes": ["https://analysis.cloudapi.de/powerbi/api/Report.Read.All https://analysis.cloudapi.de/powerbi/api/Dashboard.Read.All https://analysis.cloudapi.de/powerbi/api/Workspace.Read.All"] } } \ No newline at end of file diff --git a/.NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json b/.NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json index 57c0c5cf..de2485ae 100644 --- a/.NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json +++ b/.NET Core/Embed for your organization/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json @@ -1,5 +1,6 @@ { "AzureAd": { - "AuthorityUrl": "https://login.chinacloudapi.cn/" + "AuthorityUrl": "https://login.chinacloudapi.cn/", + "Scopes": ["https://analysis.chinacloudapi.cn/powerbi/api/Report.Read.All https://analysis.chinacloudapi.cn/powerbi/api/Dashboard.Read.All https://analysis.chinacloudapi.cn/powerbi/api/Workspace.Read.All"] } } \ No newline at end of file diff --git a/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs b/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs index b308c95a..d25bf2de 100644 --- a/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs +++ b/.NET Core/Embed for your organization/UserOwnsData/Controllers/HomeController.cs @@ -5,9 +5,9 @@ namespace UserOwnsData.Controllers { - using UserOwnsData.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; + using Microsoft.Extensions.Configuration; using Microsoft.Identity.Web; using Microsoft.Graph; using System.Threading.Tasks; @@ -20,11 +20,15 @@ public class HomeController : Controller private readonly ITokenAcquisition m_tokenAcquisition; + public IConfiguration Configuration { get; } + public HomeController(ITokenAcquisition tokenAcquisition, - GraphServiceClient graphServiceClient) + GraphServiceClient graphServiceClient, + IConfiguration configuration) { this.m_tokenAcquisition = tokenAcquisition; this.m_graphServiceClient = graphServiceClient; + Configuration = configuration; } [AllowAnonymous] @@ -34,11 +38,11 @@ public IActionResult Index() } // Redirects to login page to request increment consent - [AuthorizeForScopes(ScopeBase = new string[] { PowerBiScopes.ReadDashboard, PowerBiScopes.ReadReport, PowerBiScopes.ReadWorkspace })] + [AuthorizeForScopes(ScopeKeySection = "AzureAd:Scopes")] public async Task Embed() { // Generate token for the signed in user - var accessToken = await m_tokenAcquisition.GetAccessTokenForUserAsync(new string[] { PowerBiScopes.ReadDashboard, PowerBiScopes.ReadReport, PowerBiScopes.ReadWorkspace }); + var accessToken = await m_tokenAcquisition.GetAccessTokenForUserAsync(Configuration["AzureAd:Scopes:0"].Split(" ")); // Get username of logged in user var userInfo = await m_graphServiceClient.Me.Request().GetAsync(); diff --git a/.NET Core/Embed for your organization/UserOwnsData/Service/PowerBiScopes.cs b/.NET Core/Embed for your organization/UserOwnsData/Service/PowerBiScopes.cs deleted file mode 100644 index 307664dd..00000000 --- a/.NET Core/Embed for your organization/UserOwnsData/Service/PowerBiScopes.cs +++ /dev/null @@ -1,14 +0,0 @@ -// ---------------------------------------------------------------------------- -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// ---------------------------------------------------------------------------- - -namespace UserOwnsData.Service -{ - public class PowerBiScopes - { - public const string ReadReport = "https://analysis.windows.net/powerbi/api/Report.Read.All"; - public const string ReadDashboard = "https://analysis.windows.net/powerbi/api/Dashboard.Read.All"; - public const string ReadWorkspace = "https://analysis.windows.net/powerbi/api/Workspace.Read.All"; - } -} diff --git a/.NET Core/Embed for your organization/UserOwnsData/Startup.cs b/.NET Core/Embed for your organization/UserOwnsData/Startup.cs index 2212c114..87b20c4e 100644 --- a/.NET Core/Embed for your organization/UserOwnsData/Startup.cs +++ b/.NET Core/Embed for your organization/UserOwnsData/Startup.cs @@ -5,7 +5,6 @@ namespace UserOwnsData { - using UserOwnsData.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -21,6 +20,7 @@ public class Startup public Startup(IConfiguration configuration) { Configuration = configuration; + Configuration["AzureAd:Instance"] = Configuration["AzureAd:AuthorityUrl"]; } public IConfiguration Configuration { get; } diff --git a/.NET Core/Embed for your organization/UserOwnsData/appsettings.json b/.NET Core/Embed for your organization/UserOwnsData/appsettings.json index e03423b1..1ae981ce 100644 --- a/.NET Core/Embed for your organization/UserOwnsData/appsettings.json +++ b/.NET Core/Embed for your organization/UserOwnsData/appsettings.json @@ -1,8 +1,10 @@ { "AzureAd": { + "Instance": "", "AuthorityUrl": "https://login.microsoftonline.com/", "Domain": "", "TenantId": "common", + "Scopes": ["https://analysis.windows.net/powerbi/api/Report.Read.All https://analysis.windows.net/powerbi/api/Dashboard.Read.All https://analysis.windows.net/powerbi/api/Workspace.Read.All"], "ClientId": "", "ClientSecret": "", "CallbackPath": "/signin-oidc" diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json index 25b8005e..1cb0389a 100644 --- a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI Global/appsettings.json @@ -1,6 +1,7 @@ { "AzureAd": { "AuthorityUrl": "https://login.microsoftonline.com/organizations/", + "PowerBiApiUrl": "https://api.powerbi.com/", "ScopeBase": ["https://analysis.windows.net/powerbi/api/.default"] } } \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json index 1f1b178e..e13360b5 100644 --- a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI US Government/appsettings.json @@ -1,6 +1,7 @@ { "AzureAd": { "AuthorityUrl": "https://login.microsoftonline.com/organizations/", + "PowerBiApiUrl": "https://api.powerbigov.us/", "ScopeBase": ["https://analysis.usgovcloudapi.net/powerbi/api/.default"] } } \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json index bd36cf9b..7692a5cb 100644 --- a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI in Germany/appsettings.json @@ -1,6 +1,7 @@ { "AzureAd": { "AuthorityUrl": "https://login.microsoftonline.de/organizations/", + "PowerBiApiUrl": "https://api.powerbi.de/", "ScopeBase": ["https://analysis.cloudapi.de/powerbi/api/.default"] } } \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json index cbe77fa1..6f7e92eb 100644 --- a/.NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json +++ b/.NET Core/EncryptCredentials/CloudAppSettings/Power BI operated by 21Vianet in China/appsettings.json @@ -1,6 +1,7 @@ { "AzureAd": { "AuthorityUrl": "https://login.chinacloudapi.cn/organizations/", + "PowerBiApiUrl": "https://api.powerbi.cn/", "ScopeBase": ["https://analysis.chinacloudapi.cn/powerbi/api/.default"] } } \ No newline at end of file diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs index b6e6961d..2bb48b29 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Models/AzureAd.cs @@ -19,6 +19,9 @@ public class AzureAd // Id of the Azure tenant in which AAD app is hosted. Required only for Service Principal authentication mode. public string TenantId { get; set; } + // End point URL for REST API + public string PowerBiApiUrl { get; set; } + // ScopeBase of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. public string[] ScopeBase { get; set; } diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs index 7b8f261d..9518feb2 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Services/AadService.cs @@ -67,5 +67,9 @@ public string GetAccessToken() return authenticationResult.AccessToken; } + + public string GetPowerBiApiUrl() { + return azureAd.Value.PowerBiApiUrl; + } } } diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs b/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs index 3b5ae1c1..e0f6741b 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs +++ b/.NET Core/EncryptCredentials/EncryptCredentials/Services/PowerBIService.cs @@ -16,7 +16,6 @@ namespace EncryptCredentials.Services public class PowerBIService { private readonly AadService aadService; - private readonly string powerBiApiUrl = "https://api.powerbi.com"; public PowerBIService(AadService aadService) { @@ -30,7 +29,7 @@ public PowerBIService(AadService aadService) public PowerBIClient GetPowerBIClient() { var tokenCredentials = new TokenCredentials(aadService.GetAccessToken(), "Bearer"); - return new PowerBIClient(new Uri(powerBiApiUrl), tokenCredentials); + return new PowerBIClient(new Uri(aadService.GetPowerBiApiUrl()), tokenCredentials); } /// diff --git a/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json b/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json index 4e4d0986..f20bf934 100644 --- a/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json +++ b/.NET Core/EncryptCredentials/EncryptCredentials/appsettings.json @@ -4,6 +4,7 @@ "AuthorityUrl": "https://login.microsoftonline.com/organizations/", "ClientId": "", "TenantId": "", + "PowerBiApiUrl": "https://api.powerbi.com/", "ScopeBase": ["https://analysis.windows.net/powerbi/api/.default"], "RedirectUri": "http://localhost:5001/", "PbiUsername": "", diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java index 7b60a136..2a8ae387 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI Global/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String powerBiApiUrl = "https://api.powerbi.com/"; public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java index 34d06419..f50dc40d 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI US Government/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String powerBiApiUrl = "https://api.powerbigov.us/"; public static final String scopeBase = "https://analysis.usgovcloudapi.net/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java index be256039..af7f8b30 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI in Germany/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.microsoftonline.de/"; + public static final String powerBiApiUrl = "https://api.powerbi.de/"; public static final String scopeBase = "https://analysis.cloudapi.de/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java index 1b288fef..80606c61 100644 --- a/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java +++ b/Java/EncryptCredentials/CloudConfigs/Power BI operated by 21Vianet in China/Config.java @@ -8,5 +8,6 @@ public abstract class Config { public static final String authorityUrl = "https://login.chinacloudapi.cn/"; + public static final String powerBiApiUrl = "https://api.powerbi.cn/"; public static final String scopeBase = "https://analysis.chinacloudapi.cn/powerbi/api/.default"; } \ No newline at end of file diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java index 310e3996..f6ba6c24 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/config/Config.java @@ -35,6 +35,7 @@ public abstract class Config { // DO NOT CHANGE public static final String authorityUrl = "https://login.microsoftonline.com/"; + public static final String powerBiApiUrl = "https://api.powerbi.com/"; public static final String scopeBase = "https://analysis.windows.net/powerbi/api/.default"; private Config() { diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java index df09c28d..9aaea356 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/AddCredentialsService.java @@ -13,6 +13,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; +import com.encryptcredentialsample.encryptcredential.config.Config; import com.encryptcredentialsample.encryptcredential.models.CredentialDetails; import com.encryptcredentialsample.encryptcredential.models.GatewayPublicKey; import com.encryptcredentialsample.encryptcredential.models.PublishDatasourceToGatewayRequest; @@ -49,7 +50,7 @@ public static ResponseEntity addDataSource( public static ResponseEntity makeAddDataSourcePostRequest(String gatewayId, PublishDatasourceToGatewayRequest requestBody, String accessToken) throws ClientProtocolException, IOException { // Gateways - Create Datasource Power BI REST API // https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/createdatasource - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + gatewayId + "/datasources"; + String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/gateways/" + gatewayId + "/datasources"; // Request header HttpHeaders reqHeader = Utils.generateAuthorizationHeaders(accessToken); diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java index fefafefe..4f73f606 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/GetDatasourceData.java @@ -13,15 +13,16 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; +import com.encryptcredentialsample.encryptcredential.config.Config; import com.encryptcredentialsample.encryptcredential.models.Gateway; import com.encryptcredentialsample.encryptcredential.models.GetDatasourcesResponse; public class GetDatasourceData { - public static Gateway getGateway(String accessToken, String getwayId) { + public static Gateway getGateway(String accessToken, String gatewayId) { // REST API URL to get data sources - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + getwayId; + String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/gateways/" + gatewayId; // Request header HttpHeaders reqHeader = new HttpHeaders(); @@ -49,7 +50,7 @@ public static GetDatasourcesResponse getDatasourcesInGroup(String accessToken, S HttpEntity reqEntity = new HttpEntity<>(reqHeader); // https://docs.microsoft.com/en-us/rest/api/power-bi/datasets/getdatasourcesingroup - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/groups/" + groupId + "/datasets/" + datasetId + "/datasources"; + String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/groups/" + groupId + "/datasets/" + datasetId + "/datasources"; // Rest API get datasources's details RestTemplate getDatasourceRestTemplate = new RestTemplate(); diff --git a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java index 1bde2b5d..21e974d3 100644 --- a/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java +++ b/Java/EncryptCredentials/src/main/java/com/encryptcredentialsample/encryptcredential/services/UpdateCredentialsService.java @@ -15,6 +15,7 @@ import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; +import com.encryptcredentialsample.encryptcredential.config.Config; import com.encryptcredentialsample.encryptcredential.models.CredentialDetails; import com.encryptcredentialsample.encryptcredential.models.CredentialDetailsRequestBody; import com.encryptcredentialsample.encryptcredential.models.Gateway; @@ -77,7 +78,7 @@ public static ResponseEntity makeUpdateDataSourcePatchRequest( // Gateways - Update Datasource Power BI REST API // https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/updatedatasource - String endPointUrl = "https://api.powerbi.com/v1.0/myorg/gateways/" + gatewayId + "/datasources/" + datasourceId; + String endPointUrl = Config.powerBiApiUrl + "v1.0/myorg/gateways/" + gatewayId + "/datasources/" + datasourceId; // Request header HttpHeaders reqHeader = Utils.generateAuthorizationHeaders(accessToken); diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py index 3ec60b18..c86af4a8 100644 --- a/Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py +++ b/Python/Encrypt credentials/CloudConfigs/Power BI Global/config.py @@ -9,4 +9,7 @@ class BaseConfig(object): SCOPE_BASE = ['https://analysis.windows.net/powerbi/api/.default'] # URL used for initiating authorization request - AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' \ No newline at end of file + AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' + + # End point URL for Power BI API + POWER_BI_API_URL = 'https://api.powerbi.com/' \ No newline at end of file diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py index 67d42356..ee1a6d35 100644 --- a/Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py +++ b/Python/Encrypt credentials/CloudConfigs/Power BI US Government/config.py @@ -9,4 +9,7 @@ class BaseConfig(object): SCOPE_BASE = ['https://analysis.usgovcloudapi.net/powerbi/api/.default'] # URL used for initiating authorization request - AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' \ No newline at end of file + AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' + + # End point URL for Power BI API + POWER_BI_API_URL = 'https://api.powerbigov.us/' \ No newline at end of file diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py index cd9b414a..b23bc530 100644 --- a/Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py +++ b/Python/Encrypt credentials/CloudConfigs/Power BI in Germany/config.py @@ -9,4 +9,7 @@ class BaseConfig(object): SCOPE_BASE = ['https://analysis.cloudapi.de/powerbi/api/.default'] # URL used for initiating authorization request - AUTHORITY_URL = 'https://login.microsoftonline.de/organizations' \ No newline at end of file + AUTHORITY_URL = 'https://login.microsoftonline.de/organizations' + + # End point URL for Power BI API + POWER_BI_API_URL = 'https://api.powerbi.de/' \ No newline at end of file diff --git a/Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py b/Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py index d775bfb8..42ac1628 100644 --- a/Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py +++ b/Python/Encrypt credentials/CloudConfigs/Power BI operated by 21Vianet in China/config.py @@ -9,4 +9,7 @@ class BaseConfig(object): SCOPE_BASE = ['https://analysis.chinacloudapi.cn/powerbi/api/.default'] # URL used for initiating authorization request - AUTHORITY_URL = 'https://login.chinacloudapi.cn/organizations' \ No newline at end of file + AUTHORITY_URL = 'https://login.chinacloudapi.cn/organizations' + + # End point URL for Power BI API + POWER_BI_API_URL = 'https://api.powerbi.cn/' \ No newline at end of file diff --git a/Python/Encrypt credentials/Encryption sample/config.py b/Python/Encrypt credentials/Encryption sample/config.py index 7d20eac1..0c44c65c 100644 --- a/Python/Encrypt credentials/Encryption sample/config.py +++ b/Python/Encrypt credentials/Encryption sample/config.py @@ -21,6 +21,9 @@ class BaseConfig(object): # URL used for initiating authorization request AUTHORITY_URL = 'https://login.microsoftonline.com/organizations' + # End point URL for Power BI API + POWER_BI_API_URL = 'https://api.powerbi.com/' + # Master user email address. Required only for MasterUser authentication mode. POWER_BI_USER = '' diff --git a/Python/Encrypt credentials/Encryption sample/services/addcredentialsservice.py b/Python/Encrypt credentials/Encryption sample/services/addcredentialsservice.py index 85ed07d1..ac02507c 100644 --- a/Python/Encrypt credentials/Encryption sample/services/addcredentialsservice.py +++ b/Python/Encrypt credentials/Encryption sample/services/addcredentialsservice.py @@ -2,6 +2,7 @@ # Licensed under the MIT license. import requests +from flask import current_app as app from flask import json from models.credentialsdetails import CredentialsDetails from models.publishdatasourcetogatewayrequest import PublishDatasourceToGatewayRequest @@ -65,7 +66,7 @@ def make_add_datasource_post_request(self, gateway_id, request_body, access_toke # Gateways - Create Datasource Power BI REST API # https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/createdatasource - endpoint_url = f'https://api.powerbi.com/v1.0/myorg/gateways/{gateway_id}/datasources' + endpoint_url = f'{app.config["POWER_BI_API_URL"]}v1.0/myorg/gateways/{gateway_id}/datasources' api_response = requests.post(endpoint_url, data=json.dumps(request_body.__dict__), headers=self.headers) diff --git a/Python/Encrypt credentials/Encryption sample/services/getdatasource.py b/Python/Encrypt credentials/Encryption sample/services/getdatasource.py index 3fd80f29..0cb85132 100644 --- a/Python/Encrypt credentials/Encryption sample/services/getdatasource.py +++ b/Python/Encrypt credentials/Encryption sample/services/getdatasource.py @@ -2,7 +2,7 @@ # Licensed under the MIT license. import requests - +from flask import current_app as app class GetDatasourceService: @@ -23,7 +23,7 @@ def get_datasources_in_group(self, access_token, group_id, dataset_id): self.headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + access_token} # https://docs.microsoft.com/en-us/rest/api/power-bi/datasets/getdatasourcesingroup - endpoint_url = f'https://api.powerbi.com/v1.0/myorg/groups/{group_id}/datasets/{dataset_id}/datasources' + endpoint_url = f'{app.config["POWER_BI_API_URL"]}v1.0/myorg/groups/{group_id}/datasets/{dataset_id}/datasources' api_response = requests.get(endpoint_url, headers=self.headers) @@ -42,7 +42,7 @@ def get_gateway(self, access_token, gateway_id): self.headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + access_token} - endpoint_url = f'https://api.powerbi.com/v1.0/myorg/gateways/{gateway_id}' + endpoint_url = f'{app.config["POWER_BI_API_URL"]}v1.0/myorg/gateways/{gateway_id}' api_response = requests.get(endpoint_url, headers=self.headers) diff --git a/Python/Encrypt credentials/Encryption sample/services/updatecredentialsservice.py b/Python/Encrypt credentials/Encryption sample/services/updatecredentialsservice.py index d3760804..ff131286 100644 --- a/Python/Encrypt credentials/Encryption sample/services/updatecredentialsservice.py +++ b/Python/Encrypt credentials/Encryption sample/services/updatecredentialsservice.py @@ -2,6 +2,7 @@ # Licensed under the MIT license. import requests +from flask import current_app as app from flask import json from models.credentialsdetails import CredentialsDetails from models.credentialsdetailsrequest import CredentialsDetailsRequest @@ -72,7 +73,7 @@ def make_update_datasource_patch_request(self, credentials_details_req, gateway_ # Gateways - Update Datasource Power BI REST API # https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/updatedatasource - endpoint_url = f'https://api.powerbi.com/v1.0/myorg/gateways/{gateway_id}/datasources/{datasource_id}' + endpoint_url = f'{app.config["POWER_BI_API_URL"]}v1.0/myorg/gateways/{gateway_id}/datasources/{datasource_id}' api_response = requests.patch(endpoint_url, data=json.dumps(credentials_details_req.__dict__), headers=self.headers) From 0fadeefc71fa2761977fa14ba7d4c761da1729e1 Mon Sep 17 00:00:00 2001 From: Noam Raveh Date: Sun, 10 Jul 2022 07:46:56 +0000 Subject: [PATCH 6/8] Updated README.md - add encrypt credentials samples in main readme --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ea186c4..bea2e0de 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ This repository contains Power BI Embedded solutions in 5 different frameworks t In addition, it has samples for calling the Power BI REST APIs using PowerShell. -Available Power BI Embedded solutions: +**Available solutions for embedding Power BI content:** * Embed for your customers - aka App Owns Data * .NET Framework * .NET Core @@ -34,6 +34,11 @@ Available Power BI Embedded solutions: * .NET Core * React TS +Solutions for encrypting credentials and updating data sources are available in the following frameworks: + * .NET Core + * Python + * Node JS + > **Note:** > 1. README.md files specific to samples are present in their respective folders. From fa3c33ade5566d946822a263ed42b2f4a3954891 Mon Sep 17 00:00:00 2001 From: Atharva Bapat Date: Mon, 1 Aug 2022 11:29:58 +0000 Subject: [PATCH 7/8] Merged PR 279360: [Developer Samples]: Migrate react samples from msal to msal-react, update python requirements.txt 1. python encryption samples requirements.txt update 2. Migrating react samples from msal to @azure/msal-react References - https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/class-components.md https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react --- Python/Encrypt credentials/requirements.txt | 2 +- .../CloudConfigs/Power BI Global/Config.ts | 7 + .../Power BI US Government/Config.ts | 7 + .../Power BI in Germany/Config.ts | 7 + .../Config.ts | 7 + .../UserOwnsData/package.json | 3 +- .../UserOwnsData/src/App.tsx | 121 ++++++++---------- .../UserOwnsData/src/Config.ts | 8 ++ .../UserOwnsData/src/index.tsx | 29 ++++- 9 files changed, 123 insertions(+), 68 deletions(-) rename React-TS/{ => Embed for your organization}/CloudConfigs/Power BI Global/Config.ts (64%) rename React-TS/{ => Embed for your organization}/CloudConfigs/Power BI US Government/Config.ts (65%) rename React-TS/{ => Embed for your organization}/CloudConfigs/Power BI in Germany/Config.ts (65%) rename React-TS/{ => Embed for your organization}/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts (65%) diff --git a/Python/Encrypt credentials/requirements.txt b/Python/Encrypt credentials/requirements.txt index b8cb2952..3305f39a 100644 --- a/Python/Encrypt credentials/requirements.txt +++ b/Python/Encrypt credentials/requirements.txt @@ -1,4 +1,4 @@ cryptography==3.4.6 -Flask==1.1.2 +Flask==2.1.2 msal==1.9.0 requests==2.25.1 \ No newline at end of file diff --git a/React-TS/CloudConfigs/Power BI Global/Config.ts b/React-TS/Embed for your organization/CloudConfigs/Power BI Global/Config.ts similarity index 64% rename from React-TS/CloudConfigs/Power BI Global/Config.ts rename to React-TS/Embed for your organization/CloudConfigs/Power BI Global/Config.ts index 57537242..0d8a32a0 100644 --- a/React-TS/CloudConfigs/Power BI Global/Config.ts +++ b/React-TS/Embed for your organization/CloudConfigs/Power BI Global/Config.ts @@ -7,4 +7,11 @@ // Replace this config with the one in the Config.ts file for sovereign cloud +// URL used for initiating authorization request +export const authorityUrl: string = "https://login.microsoftonline.com/common/"; + +// End point URL for Power BI API +export const powerBiApiUrl: string = "https://api.powerbi.com"; + +// Scope for securing access token export const scopeBase: string[] = ["https://analysis.windows.net/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/CloudConfigs/Power BI US Government/Config.ts b/React-TS/Embed for your organization/CloudConfigs/Power BI US Government/Config.ts similarity index 65% rename from React-TS/CloudConfigs/Power BI US Government/Config.ts rename to React-TS/Embed for your organization/CloudConfigs/Power BI US Government/Config.ts index 4902dcb4..0e26e201 100644 --- a/React-TS/CloudConfigs/Power BI US Government/Config.ts +++ b/React-TS/Embed for your organization/CloudConfigs/Power BI US Government/Config.ts @@ -7,4 +7,11 @@ // Replace this config with the one in the Config.ts file for sovereign cloud +// URL used for initiating authorization request +export const authorityUrl: string = "https://login.microsoftonline.com/common/"; + +// End point URL for Power BI API +export const powerBiApiUrl: string = "https://api.powerbigov.us/"; + +// Scope for securing access token export const scopeBase: string[] = ["https://analysis.usgovcloudapi.net/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/CloudConfigs/Power BI in Germany/Config.ts b/React-TS/Embed for your organization/CloudConfigs/Power BI in Germany/Config.ts similarity index 65% rename from React-TS/CloudConfigs/Power BI in Germany/Config.ts rename to React-TS/Embed for your organization/CloudConfigs/Power BI in Germany/Config.ts index 3ba38d7e..b7db22fe 100644 --- a/React-TS/CloudConfigs/Power BI in Germany/Config.ts +++ b/React-TS/Embed for your organization/CloudConfigs/Power BI in Germany/Config.ts @@ -7,4 +7,11 @@ // Replace this config with the one in the Config.ts file for sovereign cloud +// URL used for initiating authorization request +export const authorityUrl: string = "https://login.microsoftonline.de/common/"; + +// End point URL for Power BI API +export const powerBiApiUrl: string = "https://api.powerbi.de/"; + +// Scope for securing access token export const scopeBase: string[] = ["https://analysis.cloudapi.de/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts b/React-TS/Embed for your organization/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts similarity index 65% rename from React-TS/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts rename to React-TS/Embed for your organization/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts index cfa23ea8..1acad4fa 100644 --- a/React-TS/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts +++ b/React-TS/Embed for your organization/CloudConfigs/Power BI operated by 21Vianet in China/Config.ts @@ -7,4 +7,11 @@ // Replace this config with the one in the Config.ts file for sovereign cloud +// URL used for initiating authorization request +export const authorityUrl: string = "https://login.chinacloudapi.cn/common/"; + +// End point URL for Power BI API +export const powerBiApiUrl: string = "https://api.powerbi.cn/"; + +// Scope for securing access token export const scopeBase: string[] = ["https://analysis.chinacloudapi.cn/powerbi/api/Report.Read.All"]; \ No newline at end of file diff --git a/React-TS/Embed for your organization/UserOwnsData/package.json b/React-TS/Embed for your organization/UserOwnsData/package.json index e4e9b0f6..166d453e 100644 --- a/React-TS/Embed for your organization/UserOwnsData/package.json +++ b/React-TS/Embed for your organization/UserOwnsData/package.json @@ -3,9 +3,10 @@ "version": "1.0.0", "private": true, "dependencies": { + "@azure/msal-browser": "^2.28.0", + "@azure/msal-react": "^1.4.4", "@types/react": "^16.9.23", "@types/react-dom": "^16.9.5", - "msal": "^1.4.1", "powerbi-client": "^2.16.5", "react": "^16.13.0", "react-app-polyfill": "^1.0.6", diff --git a/React-TS/Embed for your organization/UserOwnsData/src/App.tsx b/React-TS/Embed for your organization/UserOwnsData/src/App.tsx index e3512352..cf6aacc4 100644 --- a/React-TS/Embed for your organization/UserOwnsData/src/App.tsx +++ b/React-TS/Embed for your organization/UserOwnsData/src/App.tsx @@ -3,8 +3,9 @@ // Licensed under the MIT license. // ---------------------------------------------------------------------------- +import { AuthenticationResult, InteractionType, EventMessage, EventType, AuthError } from "@azure/msal-browser"; +import { MsalContext } from "@azure/msal-react"; import React from "react"; -import { UserAgentApplication, AuthError, AuthResponse } from "msal"; import { service, factories, models, IEmbedConfiguration } from "powerbi-client"; import "./App.css"; import * as config from "./Config"; @@ -22,6 +23,7 @@ interface AppProps { }; interface AppState { accessToken: string; embedUrl: string; error: string[] }; class App extends React.Component { + static contextType = MsalContext; constructor(props: AppProps) { super(props); @@ -103,19 +105,22 @@ class App extends React.Component { // React function componentDidMount(): void { - if (reportRef !== null) { reportContainer = reportRef["current"]; } // User input - null check if (config.workspaceId === "" || config.reportId === "") { - this.setState({ error: ["Please assign values to workspace Id and report Id in Config.ts file"] }) - } else { - - // Authenticate the user and generate the access token - this.authenticate(); + this.setState({ error: ["Please assign values to workspace Id and report Id in Config.ts file"] }); + return; } + + this.authenticate(); + } + + // React function + componentDidUpdate(): void { + this.authenticate(); } // React function @@ -125,72 +130,58 @@ class App extends React.Component { // Authenticating to get the access token authenticate(): void { - const thisObj = this; + const msalInstance = this.context.instance; + const msalAccounts = this.context.accounts; + const msalInProgress = this.context.inProgress; + const isAuthenticated = this.context.accounts.length > 0; + + if (this.state.error.length > 0) { + return; + } - const msalConfig = { - auth: { - clientId: config.clientId + const eventCallback = msalInstance.addEventCallback((message: EventMessage) => { + if (message.eventType === EventType.LOGIN_SUCCESS && !accessToken) { + const payload = message.payload as AuthenticationResult; + const name: string = payload.account?.name ? payload.account?.name: ""; + + accessToken = payload.accessToken; + this.setUsername(name); + this.tryRefreshUserPermissions(); } - }; + }); const loginRequest = { - scopes: config.scopeBase + scopes: config.scopeBase, + account: msalAccounts[0] }; - const msalInstance: UserAgentApplication = new UserAgentApplication(msalConfig); - - function successCallback(response: AuthResponse): void { - if (response.tokenType === "id_token") { - thisObj.authenticate(); - - } else if (response.tokenType === "access_token") { - - accessToken = response.accessToken; - thisObj.setUsername(response.account.name); - - // Refresh User Permissions - thisObj.tryRefreshUserPermissions(); - thisObj.getembedUrl(); - - } else { - - thisObj.setState({ error: [("Token type is: " + response.tokenType)] }); - } + if (!isAuthenticated && msalInProgress === InteractionType.None) { + msalInstance.loginRedirect(loginRequest); } - - function failCallBack(error: AuthError): void { - thisObj.setState({ error: ["Redirect error: " + error] }); + else if (isAuthenticated && accessToken && !embedUrl) { + this.getembedUrl(); + msalInstance.removeEventCallback(eventCallback); } - - msalInstance.handleRedirectCallback(successCallback, failCallBack); - - // check if there is a cached user - if (msalInstance.getAccount()) { + else if (isAuthenticated && !accessToken && !embedUrl && msalInProgress === InteractionType.None) { + this.setUsername(msalAccounts[0].name); // get access token silently from cached id-token - msalInstance.acquireTokenSilent(loginRequest) - .then((response: AuthResponse) => { - - // get access token from response: response.accessToken - accessToken = response.accessToken; - this.setUsername(response.account.name); - this.getembedUrl(); - }) - .catch((err: AuthError) => { - - // refresh access token silently from cached id-token - // makes the call to handleredirectcallback - if (err.name === "InteractionRequiredAuthError") { - msalInstance.acquireTokenRedirect(loginRequest); - } - else { - thisObj.setState({ error: [err.toString()] }) - } - }); - } else { - - // user is not logged in or cached, you will need to log them in to acquire a token - msalInstance.loginRedirect(loginRequest); + msalInstance.acquireTokenSilent(loginRequest).then((response: AuthenticationResult) => { + accessToken = response.accessToken; + this.getembedUrl(); + }).catch((error: AuthError) => { + // Refresh access token silently from cached id-token + // Makes the call to handleredirectcallback + if (error.errorCode === "consent_required" || error.errorCode === "interaction_required" || error.errorCode === "login_required") { + msalInstance.acquireTokenRedirect(loginRequest); + } + else if (error.errorCode === '429') { + this.setState({ error: ["Our Service Token Server (STS) is overloaded, please try again in sometime"] }); + } + else { + this.setState({ error: ["There was some problem fetching the access token" + error.toString()] }); + } + }); } } @@ -198,7 +189,7 @@ class App extends React.Component { // Refreshes user permissions and makes sure the user permissions are fully updated // https://docs.microsoft.com/rest/api/power-bi/users/refreshuserpermissions tryRefreshUserPermissions(): void { - fetch("https://api.powerbi.com/v1.0/myorg/RefreshUserPermissions", { + fetch(config.powerBiApiUrl + "v1.0/myorg/RefreshUserPermissions", { headers: { "Authorization": "Bearer " + accessToken }, @@ -225,7 +216,7 @@ class App extends React.Component { getembedUrl(): void { const thisObj: this = this; - fetch("https://api.powerbi.com/v1.0/myorg/groups/" + config.workspaceId + "/reports/" + config.reportId, { + fetch(config.powerBiApiUrl + "v1.0/myorg/groups/" + config.workspaceId + "/reports/" + config.reportId, { headers: { "Authorization": "Bearer " + accessToken }, diff --git a/React-TS/Embed for your organization/UserOwnsData/src/Config.ts b/React-TS/Embed for your organization/UserOwnsData/src/Config.ts index fc99a0d4..be8fff27 100644 --- a/React-TS/Embed for your organization/UserOwnsData/src/Config.ts +++ b/React-TS/Embed for your organization/UserOwnsData/src/Config.ts @@ -7,6 +7,14 @@ // Scope Base of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal. // Refer https://aka.ms/PowerBIPermissions for complete list of Power BI scopes + +// URL used for initiating authorization request +export const authorityUrl: string = "https://login.microsoftonline.com/common/"; + +// End point URL for Power BI API +export const powerBiApiUrl: string = "https://api.powerbi.com/"; + +// Scope for securing access token export const scopeBase: string[] = ["https://analysis.windows.net/powerbi/api/Report.Read.All"]; // Client Id (Application Id) of the AAD app. diff --git a/React-TS/Embed for your organization/UserOwnsData/src/index.tsx b/React-TS/Embed for your organization/UserOwnsData/src/index.tsx index 1664caa9..e056efdc 100644 --- a/React-TS/Embed for your organization/UserOwnsData/src/index.tsx +++ b/React-TS/Embed for your organization/UserOwnsData/src/index.tsx @@ -3,10 +3,37 @@ // Licensed under the MIT license. // ---------------------------------------------------------------------------- +import { PublicClientApplication } from "@azure/msal-browser"; +import { MsalProvider } from "@azure/msal-react"; import 'react-app-polyfill/ie11'; import 'react-app-polyfill/stable'; import React from 'react'; import ReactDOM from 'react-dom'; + import App from './App'; +import * as config from "./Config"; + +const msalInstanceProvider = new PublicClientApplication(generateMsalConfig()); + +ReactDOM.render( + + +, +document.getElementById('root')); + +// Refer https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react#configure-your-javascript-spa +function generateMsalConfig() { + const msalConfig = { + auth: { + clientId: config.clientId, + authority: config.authorityUrl, + redirectUri: "http://localhost:3000", + }, + cache: { + cacheLocation: "sessionStorage", // This configures where your cache will be stored + storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge + } + }; -ReactDOM.render(, document.getElementById('root')); \ No newline at end of file + return msalConfig; +} \ No newline at end of file From 7bf03a9cb1642e0f3cbf25f36b75eabf08a7e902 Mon Sep 17 00:00:00 2001 From: Kotana Sai Date: Wed, 17 Aug 2022 11:04:48 +0000 Subject: [PATCH 8/8] Merged PR 285470: Developer samples - NodeJS: Upgrade sample to use MSAL authentication library instead of ADAL Upgrade NodeJS samples to use MSAL authentication library instead of ADAL 1. Master User Authentication ![image.png](https://dev.azure.com/powerbi/4c7b5adb-c2d0-4f18-b23c-edc4ac30f4e1/_apis/git/repositories/018fac5b-133f-45a1-b1a2-dfe0e0821916/pullRequests/285470/attachments/image.png) 2. Service Principal Authentication ![image (2).png](https://dev.azure.com/powerbi/4c7b5adb-c2d0-4f18-b23c-edc4ac30f4e1/_apis/git/repositories/018fac5b-133f-45a1-b1a2-dfe0e0821916/pullRequests/285470/attachments/image%20%282%29.png) Related work items: #769133 --- .../AppOwnsData/config/config.json | 4 +- .../AppOwnsData/package.json | 2 +- .../AppOwnsData/src/authentication.js | 74 ++++++++----------- 3 files changed, 35 insertions(+), 45 deletions(-) diff --git a/NodeJS/Embed for your customers/AppOwnsData/config/config.json b/NodeJS/Embed for your customers/AppOwnsData/config/config.json index 658a6954..4b142fe5 100644 --- a/NodeJS/Embed for your customers/AppOwnsData/config/config.json +++ b/NodeJS/Embed for your customers/AppOwnsData/config/config.json @@ -1,7 +1,7 @@ { "authenticationMode": "MasterUser", - "authorityUrl": "https://login.microsoftonline.com/common/v2.0", - "scopeBase": "https://analysis.windows.net/powerbi/api", + "authorityUrl": "https://login.microsoftonline.com/", + "scopeBase": "https://analysis.windows.net/powerbi/api/.default", "powerBiApiUrl": "https://api.powerbi.com/", "clientId": "", "workspaceId": "", diff --git a/NodeJS/Embed for your customers/AppOwnsData/package.json b/NodeJS/Embed for your customers/AppOwnsData/package.json index af57bba0..f36ba2c2 100644 --- a/NodeJS/Embed for your customers/AppOwnsData/package.json +++ b/NodeJS/Embed for your customers/AppOwnsData/package.json @@ -11,7 +11,7 @@ "author": "", "license": "ISC", "dependencies": { - "adal-node": "^0.2.1", + "@azure/msal-node": "^1.12.0", "body-parser": "^1.19.0", "bootstrap": "^4.4.1", "express": "^4.17.1", diff --git a/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js b/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js index 771d3c05..ff94065a 100644 --- a/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js +++ b/NodeJS/Embed for your customers/AppOwnsData/src/authentication.js @@ -4,53 +4,43 @@ // ---------------------------------------------------------------------------- const getAccessToken = async function () { - - // Use ADAL.js for authentication - let adal = require("adal-node"); - - let AuthenticationContext = adal.AuthenticationContext; - // Create a config variable that store credentials from config.json - let config = require(__dirname + "/../config/config.json"); + const config = require(__dirname + "/../config/config.json"); - let authorityUrl = config.authorityUrl; + // Use MSAL.js for authentication + const msal = require("@azure/msal-node"); + + const msalConfig = { + auth: { + clientId: config.clientId, + authority: `${config.authorityUrl}${config.tenantId}`, + } + }; // Check for the MasterUser Authentication if (config.authenticationMode.toLowerCase() === "masteruser") { - let context = new AuthenticationContext(authorityUrl); - - return new Promise( - (resolve, reject) => { - context.acquireTokenWithUsernamePassword(config.scopeBase, config.pbiUsername, config.pbiPassword, config.clientId, function (err, tokenResponse) { - - // Function returns error object in tokenResponse - // Invalid Username will return empty tokenResponse, thus err is used - if (err) { - reject(tokenResponse == null ? err : tokenResponse); - } - resolve(tokenResponse); - }) - } - ); - - // Service Principal auth is the recommended by Microsoft to achieve App Owns Data Power BI embedding - } else if (config.authenticationMode.toLowerCase() === "serviceprincipal") { - authorityUrl = authorityUrl.replace("common", config.tenantId); - let context = new AuthenticationContext(authorityUrl); - - return new Promise( - (resolve, reject) => { - context.acquireTokenWithClientCredentials(config.scopeBase, config.clientId, config.clientSecret, function (err, tokenResponse) { - - // Function returns error object in tokenResponse - // Invalid Username will return empty tokenResponse, thus err is used - if (err) { - reject(tokenResponse == null ? err : tokenResponse); - } - resolve(tokenResponse); - }) - } - ); + const clientApplication = new msal.PublicClientApplication(msalConfig); + + const usernamePasswordRequest = { + scopes: [config.scopeBase], + username: config.pbiUsername, + password: config.pbiPassword + }; + + return clientApplication.acquireTokenByUsernamePassword(usernamePasswordRequest); + + }; + + // Service Principal auth is the recommended by Microsoft to achieve App Owns Data Power BI embedding + if (config.authenticationMode.toLowerCase() === "serviceprincipal") { + msalConfig.auth.clientSecret = config.clientSecret + const clientApplication = new msal.ConfidentialClientApplication(msalConfig); + + const clientCredentialRequest = { + scopes: [config.scopeBase], + }; + + return clientApplication.acquireTokenByClientCredential(clientCredentialRequest); } }