Skip to content

Commit

Permalink
Merge pull request #715 from neelavarshad/single-tenant-admin
Browse files Browse the repository at this point in the history
Changed Admin app to single tenant
  • Loading branch information
santhoshb-msft authored Aug 14, 2024
2 parents c810995 + 03d7e28 commit 5433873
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 39 deletions.
43 changes: 30 additions & 13 deletions deployment/Deploy.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ Param(
[string][Parameter()]$AzureSubscriptionID, # Subscription where the resources be deployed
[string][Parameter()]$ADApplicationID, # The value should match the value provided for Active Directory Application ID in the Technical Configuration of the Transactable Offer in Partner Center
[string][Parameter()]$ADApplicationSecret, # Secret key of the AD Application
[string][Parameter()]$ADMTApplicationIDAdmin, # Multi-Tenant Active Directory Application ID for the Admin Portal
[string][Parameter()]$ADApplicationIDAdmin, # Multi-Tenant Active Directory Application ID
[string][Parameter()]$ADMTApplicationIDPortal, #Multi-Tenant Active Directory Application ID for the Landing Portal
[string][Parameter()]$IsAdminPortalMultiTenant, # If set to true, the Admin Portal will be configured as a multi-tenant application. This is by default set to false.
[string][Parameter()]$SQLDatabaseName, # Name of the database (Defaults to AMPSaaSDB)
[string][Parameter()]$SQLServerName, # Name of the database server (without database.windows.net)
[string][Parameter()]$LogoURLpng, # URL for Publisher .png logo
Expand Down Expand Up @@ -214,23 +215,39 @@ if($LogoURLico) {
#region Create AAD App Registrations

#Record the current ADApps to reduce deployment instructions at the end
$ISADMTApplicationIDProvided = ($ADMTApplicationIDAdmin && $ADMTApplicationIDPortal)
$ISLoginAppProvided = ($ADApplicationIDAdmin -ne "" -or $ADMTApplicationIDPortal -ne "")

if($ISADMTApplicationIDProvided -eq $null){

if($ISLoginAppProvided){
Write-Host "🔑 Multi-Tenant App Registrations provided."
Write-Host " ➡️ Admin Portal App Registration ID:" $ADMTApplicationIDAdmin
Write-Host " ➡️ Admin Portal App Registration ID:" $ADApplicationIDAdmin
Write-Host " ➡️ Landing Page App Registration ID:" $ADMTApplicationIDPortal
}
else {
Write-Host "🔑 Multi-Tenant App Registrations not provided."
}



if($IsAdminPortalMultiTenant -eq "true"){
Write-Host "🔑 Admin Portal App Registration set as Multi-Tenant."
$IsAdminPortalMultiTenant = $true
}
else {
Write-Host "🔑 Admin Portal App Registration set as Single-Tenant."
$IsAdminPortalMultiTenant = $false
}






#Create App Registration for authenticating calls to the Marketplace API
if (!($ADApplicationID)) {
Write-Host "🔑 Creating Fulfilment API App Registration"
try {
$ADApplication = az ad app create --only-show-errors --display-name "$WebAppNamePrefix-FulfillmentAppReg" | ConvertFrom-Json
$ADApplication = az ad app create --only-show-errors --sign-in-audience AzureADMYOrg --display-name "$WebAppNamePrefix-FulfillmentAppReg" | ConvertFrom-Json
$ADObjectID = $ADApplication.id
$ADApplicationID = $ADApplication.appId
sleep 5 #this is to give time to AAD to register
Expand All @@ -248,7 +265,7 @@ if (!($ADApplicationID)) {
}

#Create Multi-Tenant App Registration for Admin Portal User Login
if (!($ADMTApplicationID)) {
if (!($ADApplicationIDAdmin)) {
Write-Host "🔑 Creating Admin Portal SSO App Registration"
try {

Expand All @@ -259,7 +276,7 @@ if (!($ADMTApplicationID)) {
{
"requestedAccessTokenVersion" : 2
},
"signInAudience" : "AzureADandPersonalMicrosoftAccount",
"signInAudience" : "AzureADMyOrg",
"web":
{
"redirectUris":
Expand Down Expand Up @@ -293,11 +310,11 @@ if (!($ADMTApplicationID)) {

$adminPortalAppReg = $(az rest --method POST --headers "Content-Type=application/json" --uri https://graph.microsoft.com/v1.0/applications --body $appCreateRequestBodyJson ) | ConvertFrom-Json

$ADMTApplicationIDAdmin = $adminPortalAppReg.appId
$ADApplicationIDAdmin = $adminPortalAppReg.appId
$ADMTObjectIDAdmin = $adminPortalAppReg.id

Write-Host " 🔵 Admin Portal SSO App Registration created."
Write-Host " ➡️ Application Id: $ADMTApplicationIDAdmin"
Write-Host " ➡️ Application Id: $ADApplicationIDAdmin"


# Download Publisher's AppRegistration logo
Expand Down Expand Up @@ -326,7 +343,7 @@ if (!($ADMTApplicationID)) {
}

#Create Multi-Tenant App Registration for Landing Page User Login
if (!($ADMTApplicationID)) {
if (!($ADMTApplicationIDPortal)) {
Write-Host "🔑 Creating Landing Page SSO App Registration"
try {

Expand Down Expand Up @@ -489,7 +506,7 @@ Write-host " ➡️ Setup access to KeyVault"
az keyvault set-policy --name $KeyVault --object-id $WebAppNameAdminId --secret-permissions get list --key-permissions get list --resource-group $ResourceGroupForDeployment --output $azCliOutput
Write-host " ➡️ Set Configuration"
az webapp config connection-string set -g $ResourceGroupForDeployment -n $WebAppNameAdmin -t SQLAzure --output $azCliOutput --settings DefaultConnection=$DefaultConnectionKeyVault
az webapp config appsettings set -g $ResourceGroupForDeployment -n $WebAppNameAdmin --output $azCliOutput --settings KnownUsers=$PublisherAdminUsers SaaSApiConfiguration__AdAuthenticationEndPoint=https://login.microsoftonline.com SaaSApiConfiguration__ClientId=$ADApplicationID SaaSApiConfiguration__ClientSecret=$ADApplicationSecretKeyVault SaaSApiConfiguration__FulFillmentAPIBaseURL=https://marketplaceapi.microsoft.com/api SaaSApiConfiguration__FulFillmentAPIVersion=2018-08-31 SaaSApiConfiguration__GrantType=client_credentials SaaSApiConfiguration__MTClientIdAdmin=$ADMTApplicationIDAdmin SaaSApiConfiguration__MTCLientIdPortal=$ADMTApplicationIDPortal SaaSApiConfiguration__Resource=20e940b3-4c77-4b0b-9a53-9e16a1b010a7 SaaSApiConfiguration__TenantId=$TenantID SaaSApiConfiguration__SignedOutRedirectUri=https://$WebAppNamePrefix-admin.azurewebsites.net/Home/Index/ SaaSApiConfiguration_CodeHash=$SaaSApiConfiguration_CodeHash
az webapp config appsettings set -g $ResourceGroupForDeployment -n $WebAppNameAdmin --output $azCliOutput --settings KnownUsers=$PublisherAdminUsers SaaSApiConfiguration__AdAuthenticationEndPoint=https://login.microsoftonline.com SaaSApiConfiguration__ClientId=$ADApplicationID SaaSApiConfiguration__ClientSecret=$ADApplicationSecretKeyVault SaaSApiConfiguration__FulFillmentAPIBaseURL=https://marketplaceapi.microsoft.com/api SaaSApiConfiguration__FulFillmentAPIVersion=2018-08-31 SaaSApiConfiguration__GrantType=client_credentials SaaSApiConfiguration__MTClientId=$ADApplicationIDAdmin SaaSApiConfiguration__IsAdminPortalMultiTenant=$IsAdminPortalMultiTenant SaaSApiConfiguration__Resource=20e940b3-4c77-4b0b-9a53-9e16a1b010a7 SaaSApiConfiguration__TenantId=$TenantID SaaSApiConfiguration__SignedOutRedirectUri=https://$WebAppNamePrefix-admin.azurewebsites.net/Home/Index/ SaaSApiConfiguration_CodeHash=$SaaSApiConfiguration_CodeHash
az webapp config set -g $ResourceGroupForDeployment -n $WebAppNameAdmin --always-on true --output $azCliOutput

Write-host " 🔵 Customer Portal WebApp"
Expand All @@ -501,7 +518,7 @@ Write-host " ➡️ Setup access to KeyVault"
az keyvault set-policy --name $KeyVault --object-id $WebAppNamePortalId --secret-permissions get list --key-permissions get list --resource-group $ResourceGroupForDeployment --output $azCliOutput
Write-host " ➡️ Set Configuration"
az webapp config connection-string set -g $ResourceGroupForDeployment -n $WebAppNamePortal -t SQLAzure --output $azCliOutput --settings DefaultConnection=$DefaultConnectionKeyVault
az webapp config appsettings set -g $ResourceGroupForDeployment -n $WebAppNamePortal --output $azCliOutput --settings SaaSApiConfiguration__AdAuthenticationEndPoint=https://login.microsoftonline.com SaaSApiConfiguration__ClientId=$ADApplicationID SaaSApiConfiguration__ClientSecret=$ADApplicationSecretKeyVault SaaSApiConfiguration__FulFillmentAPIBaseURL=https://marketplaceapi.microsoft.com/api SaaSApiConfiguration__FulFillmentAPIVersion=2018-08-31 SaaSApiConfiguration__GrantType=client_credentials SaaSApiConfiguration__MTClientIdPortal=$ADMTApplicationIDPortal SaaSApiConfiguration__MTClientIdAdmin=$ADMTApplicationIDAdmin SaaSApiConfiguration__Resource=20e940b3-4c77-4b0b-9a53-9e16a1b010a7 SaaSApiConfiguration__TenantId=$TenantID SaaSApiConfiguration__SignedOutRedirectUri=https://$WebAppNamePrefix-portal.azurewebsites.net/Home/Index/ SaaSApiConfiguration_CodeHash=$SaaSApiConfiguration_CodeHash
az webapp config appsettings set -g $ResourceGroupForDeployment -n $WebAppNamePortal --output $azCliOutput --settings SaaSApiConfiguration__AdAuthenticationEndPoint=https://login.microsoftonline.com SaaSApiConfiguration__ClientId=$ADApplicationID SaaSApiConfiguration__ClientSecret=$ADApplicationSecretKeyVault SaaSApiConfiguration__FulFillmentAPIBaseURL=https://marketplaceapi.microsoft.com/api SaaSApiConfiguration__FulFillmentAPIVersion=2018-08-31 SaaSApiConfiguration__GrantType=client_credentials SaaSApiConfiguration__MTClientId=$ADMTApplicationIDPortal SaaSApiConfiguration__Resource=20e940b3-4c77-4b0b-9a53-9e16a1b010a7 SaaSApiConfiguration__TenantId=$TenantID SaaSApiConfiguration__SignedOutRedirectUri=https://$WebAppNamePrefix-portal.azurewebsites.net/Home/Index/ SaaSApiConfiguration_CodeHash=$SaaSApiConfiguration_CodeHash
az webapp config set -g $ResourceGroupForDeployment -n $WebAppNamePortal --always-on true --output $azCliOutput

#endregion
Expand Down Expand Up @@ -542,7 +559,7 @@ Remove-Item -Path script.sql
#region Present Output

Write-host "✅ If the intallation completed without error complete the folllowing checklist:"
if ($ISADMTApplicationIDProvided -ne $null) { #If provided then show the user where to add the landing page in AAD, otherwise script did this already for the user.
if ($ISLoginAppProvided) { #If provided then show the user where to add the landing page in AAD, otherwise script did this already for the user.
Write-host " 🔵 Add The following URLs to the multi-tenant Landing Page AAD App Registration in Azure Portal:"
Write-host " ➡️ https://$WebAppNamePrefix-portal.azurewebsites.net"
Write-host " ➡️ https://$WebAppNamePrefix-portal.azurewebsites.net/"
Expand Down
1 change: 1 addition & 0 deletions docs/Advanced-Instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
| SQLServerName | A unique name of the database server (without database.windows.net). Default: `WebAppNamePrefix`-sql |
| LogoURLpng | The url of the company logo image in .png format with a size of 96x96 to be used on the website |
| LogoURLico | The url of the company logo image in .ico format |
| IsAdminPortalMultiTenant | Set to `true` if you want to enable multi-tenant support for the admin portal. Default: `false` |
| Quiet | Disable verbose output when running the script


Expand Down
2 changes: 2 additions & 0 deletions docs/Installation-Instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ The script above will perform the following actions.
-ADMTApplicationID "xxxx-xxx-xxx-xxx-xxxx" `
-LogoURLpng "https://company_com/company_logo.png" `
-LogoURLico "https://company_com/company_logo.ico" `
-IsAdminPortalMultiTenant "true" `
-Quiet
```

Expand Down Expand Up @@ -107,6 +108,7 @@ cd ./Commercial-Marketplace-SaaS-Accelerator/deployment; `
| SQLServerName | A unique name of the database server (without database.windows.net). Default: `WebAppNamePrefix`-sql |
| LogoURLpng | The url of the company logo image in .png format with a size of 96x96 to be used on the website |
| LogoURLico | The url of the company logo image in .ico format |
| IsAdminPortalMultiTenant | Set to `true` if you want to enable multi-tenant support for the admin portal. Default: `false` |
| Quiet | Disable verbose output when running the script

## Setting up a development environment
Expand Down
21 changes: 16 additions & 5 deletions src/AdminSite/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.Marketplace.Metering;
using Microsoft.Marketplace.SaaS;
Expand Down Expand Up @@ -71,20 +72,22 @@ public void ConfigureServices(IServiceCollection services)
ClientId = this.Configuration["SaaSApiConfiguration:ClientId"] ?? Guid.Empty.ToString(),
ClientSecret = this.Configuration["SaaSApiConfiguration:ClientSecret"] ?? String.Empty,
FulFillmentAPIBaseURL = this.Configuration["SaaSApiConfiguration:FulFillmentAPIBaseURL"],
MTClientIdAdmin = this.Configuration["SaaSApiConfiguration:MTClientIdAdmin"] ?? Guid.Empty.ToString(),
MTClientIdPortal = this.Configuration["SaaSApiConfiguration:MTClientIdPortal"] ?? Guid.Empty.ToString(),
MTClientId = this.Configuration["SaaSApiConfiguration:MTClientId"] ?? Guid.Empty.ToString(),
FulFillmentAPIVersion = this.Configuration["SaaSApiConfiguration:FulFillmentAPIVersion"],
GrantType = this.Configuration["SaaSApiConfiguration:GrantType"],
Resource = this.Configuration["SaaSApiConfiguration:Resource"],
SaaSAppUrl = this.Configuration["SaaSApiConfiguration:SaaSAppUrl"],
SignedOutRedirectUri = this.Configuration["SaaSApiConfiguration:SignedOutRedirectUri"],
TenantId = this.Configuration["SaaSApiConfiguration:TenantId"] ?? Guid.Empty.ToString()
TenantId = this.Configuration["SaaSApiConfiguration:TenantId"] ?? Guid.Empty.ToString(),
IsAdminPortalMultiTenant = this.Configuration["SaaSApiConfiguration:IsAdminPortalMultiTenant"]
};
var knownUsers = new KnownUsersModel()
{
KnownUsers = this.Configuration["KnownUsers"],
};
var creds = new ClientSecretCredential(config.TenantId.ToString(), config.ClientId.ToString(), config.ClientSecret);
var boolMultiTenant = config.IsAdminPortalMultiTenant?.ToLower().Trim() ?? "false";



services
Expand All @@ -96,8 +99,16 @@ public void ConfigureServices(IServiceCollection services)
})
.AddOpenIdConnect(options =>
{
options.Authority = $"{config.AdAuthenticationEndPoint}/common/v2.0";
options.ClientId = config.MTClientIdAdmin;

if (boolMultiTenant == "false")
{
options.Authority = $"{config.AdAuthenticationEndPoint}/{config.TenantId}/v2.0";
}
else
{
options.Authority = $"{config.AdAuthenticationEndPoint}/common/v2.0";
}
options.ClientId = config.MTClientId;
options.ResponseType = OpenIdConnectResponseType.IdToken;
options.CallbackPath = "/Home/Index";
options.SignedOutRedirectUri = config.SignedOutRedirectUri;
Expand Down
4 changes: 2 additions & 2 deletions src/AdminSite/appsettings.Development.json.rename
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// "tenantid": "",
// "clientid": "",
// "clientsecret": "",
// "mtclientidadmin": "",
// "mtclientidportal": "",
// "mtclientid": "",
// "isadminportalmultitenant" : "false",
// "resource": "20e940b3-4c77-4b0b-9a53-9e16a1b010a7",
// "fulfillmentapibaseurl": "https://marketplaceapi.microsoft.com/api",
// "signedoutredirecturi": "",
Expand Down
4 changes: 2 additions & 2 deletions src/AdminSite/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// "tenantid": "",
// "clientid": "",
// "clientsecret": "",
// "mtclientidadmin": "",
// "mtclientidportal": "",
// "mtclientid": "",
// "isadminportalmultitenant" : "false",
// "resource": "20e940b3-4c77-4b0b-9a53-9e16a1b010a7",
// "fulfillmentapibaseurl": "https://marketplaceapi.microsoft.com/api",
// "signedoutredirecturi": "",
Expand Down
5 changes: 2 additions & 3 deletions src/CustomerSite/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ public void ConfigureServices(IServiceCollection services)
AdAuthenticationEndPoint = this.Configuration["SaaSApiConfiguration:AdAuthenticationEndPoint"],
ClientId = this.Configuration["SaaSApiConfiguration:ClientId"],
ClientSecret = this.Configuration["SaaSApiConfiguration:ClientSecret"],
MTClientIdAdmin = this.Configuration["SaaSApiConfiguration:MTClientIdAdmin"],
MTClientIdPortal = this.Configuration["SaaSApiConfiguration:MTClientIdPortal"],
MTClientId = this.Configuration["SaaSApiConfiguration:MTClientId"],
FulFillmentAPIBaseURL = this.Configuration["SaaSApiConfiguration:FulFillmentAPIBaseURL"],
FulFillmentAPIVersion = this.Configuration["SaaSApiConfiguration:FulFillmentAPIVersion"],
GrantType = this.Configuration["SaaSApiConfiguration:GrantType"],
Expand Down Expand Up @@ -96,7 +95,7 @@ public void ConfigureServices(IServiceCollection services)
.AddOpenIdConnect(options =>
{
options.Authority = $"{config.AdAuthenticationEndPoint}/common/v2.0";
options.ClientId = config.MTClientIdPortal;
options.ClientId = config.MTClientId;
options.ResponseType = OpenIdConnectResponseType.IdToken;
options.CallbackPath = "/Home/Index";
options.SignedOutRedirectUri = config.SignedOutRedirectUri;
Expand Down
3 changes: 1 addition & 2 deletions src/CustomerSite/appsettings.Development.json.rename
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
// "tenantid": "",
// "clientid": "",
// "clientsecret": "",
// "mtclientidadmin": "",
// "mtclientidportal": "",
// "mtclientid": "",
// "resource": "20e940b3-4c77-4b0b-9a53-9e16a1b010a7",
// "fulfillmentapibaseurl": "https://marketplaceapi.microsoft.com/api",
// "signedoutredirecturi": "",
Expand Down
5 changes: 2 additions & 3 deletions src/CustomerSite/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@

// "granttype": "client_credentials",
// "clientid": "",
// "clientsecret": "",
// "mtclientidadmin": "",
// "mtclientidportal": "",
// "clientsecret": ""
// "mtclientid": "",
// "tenantid": "",
// "resource": "20e940b3-4c77-4b0b-9a53-9e16a1b010a7",
// "fulfillmentapibaseurl": "https://marketplaceapi.microsoft.com/api",
Expand Down
19 changes: 10 additions & 9 deletions src/Services/Configurations/SaaSApiClientConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for license information.
using System;

namespace Marketplace.SaaS.Accelerator.Services.Configurations;

/// <summary>
Expand Down Expand Up @@ -37,15 +39,7 @@ public class SaaSApiClientConfiguration
/// <value>
/// The resource.
/// </value>
public string MTClientIdAdmin { get; set; }

/// <summary>
/// Gets or sets the AAD Client ID resource.
/// </summary>
/// <value>
/// The resource.
/// </value>
public string MTClientIdPortal { get; set; }
public string MTClientId { get; set; }

/// <summary>
/// Gets or sets the resource.
Expand Down Expand Up @@ -111,6 +105,13 @@ public class SaaSApiClientConfiguration
/// The production-level environment. Typically, "development", "production", or null.
/// </value>
public string Environment { get; init; }
/// <summary>
/// Initializes or Gets the value for IsAdminPortalMultiTenant. Set to true or false is assumed.
/// </summary>
/// <value>
/// The value for IsAdminPortalMultiTenant. Typically, true, false, or null.
/// </value>
public string IsAdminPortalMultiTenant { get; set; }


}

0 comments on commit 5433873

Please sign in to comment.