Most of you familiar with Windows Azure Pack may know about this article where you can use ACS to integrate Windows Azure Pack with AAD. (https://blogs.technet.microsoft.com/privatecloud/2014/01/17/setting-up-windows-azure-active-directory-acs-to-provide-identities-to-windows-azure-pack/)
With ACS retired in November of 2018, existing Windows Azure Pack configuration that use ACS is broken! So what is the alternative?
Basically the only configuration that would achieve the same integration with AAD is to use an on-premise AD FS that use AAD as its claim provider for the relying party in question (Admin/Tenant Site)
The reason behind that is that AADs WS-Fed implementation only returns SAML tokens while Azure Pack requires JWT for WS-Fed request.
The below links discuss how to use Azure AD as claim provider in AD FS
https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/adfs
For step by step instruction please follow the below instructions:
Add ADFS as application in Azure Active Directory (Azure AD)
Note: Following properties need to set for ADFS application
- App Id Url: http://<your-adfs-endpoint>/adfs/services/trust
- Home Page Url: http://<your-adfs-endpoint>/adfs/services/trust
- Reply Url: https://<your-adfs-endpoint>/adfs/ls/
Add Azure Active Directory (Azure AD) as claims provider and Admin/Tenant Site as relying party in ADFS
Run following PowerShell in ADFS machine
- Start PowerShell as Administrator
- Copy and paste the below script to ConfigureADFSWithAzureAD.ps1 and pass in following values
- Azure AD directory tenant federation metadata endpoint
- Tenant Site federation metadata endpoint
- Admin Site federation metadata endpoint (Only if you like to configure admin site with Azure AD)
# PowerShell script to configure AD FS
# Copyright (c) Microsoft Corporation. All rights reserved.
Param(
[Parameter(Mandatory=$true)][string]$identityProviderMetadataEndpoint,
[Parameter(Mandatory=$true)][string]$tenantRelyingPartyMetadataEndpoint,
[string]$adminRelyingPartyMetadataEndpoint,
[string]$identityProviderName,
[string]$tenantRelyingPartyName,
[string]$adminRelyingPartyName,
[switch]$allowSelfSignCertificates)
Import-Module -Name 'ADFS'
if (!$identityProviderName)
{
$identityProviderName = "Azure AD"
}
if (!$tenantRelyingPartyName)
{
$tenantRelyingPartyName = "MgmtSvc-TenantSite"
}
if (!$adminRelyingPartyName)
{
$adminRelyingPartyName = "MgmtSvc-AdminSite"
}
Write-Verbose -Message "identityProviderMetadataEndpoint: $identityProviderMetadataEndpoint"
Write-Verbose -Message "tenantRelyingPartyMetadataEndpoint: $tenantRelyingPartyMetadataEndpoint"
Write-Verbose -Message "adminRelyingPartyMetadataEndpoint: $adminRelyingPartyMetadataEndpoint"
Write-Verbose -Message "identityProviderName: $identityProviderName"
Write-Verbose -Message "tenantRelyingPartyName: $tenantRelyingPartyName"
Write-Verbose -Message "adminRelyingPartyName: $adminRelyingPartyName"
Write-Verbose -Message "allowSelfSignCertificates: $allowSelfSignCertificates"
$OriginalServerCertificateValidationCallback = [Net.ServicePointManager]::ServerCertificateValidationCallback
if ($allowSelfSignCertificates)
{
[Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
}
try
{
$identityProvider = Get-AdfsClaimsProviderTrust -Name $identityProviderName
if ($identityProvider)
{
Write-Verbose -Message "Removing existing identity provider $identityProviderName"
Remove-AdfsClaimsProviderTrust -TargetName $identityProviderName
}
Write-Verbose -Message "Creating identity provider $identityProviderName"
$acceptanceTransformRules = (
"@RuleTemplate = ""PassThroughClaims"" @RuleName = ""Groups - Passthrough"" c:[Type == ""http://schemas.xmlsoap.org/claims/Group""] => issue(claim = c);",
"@RuleTemplate = ""PassThroughClaims"" @RuleName = ""Name - Passthrough"" c:[Type == ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name""] => issue(claim = c);",
"@RuleTemplate = ""PassThroughClaims"" @RuleName = ""DisplayName - Passthrough"" c:[Type == ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname""] => issue(claim = c);",
"@RuleTemplate = ""MapClaims"" @RuleName = ""NameToUPN"" c:[Type == ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name""] => issue(Type = ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType);",
"@RuleTemplate = ""MapClaims"" @RuleName = ""EmailToUPN"" c:[Type == ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress""] => issue(Type = ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType);")
Add-AdfsClaimsProviderTrust `
-Name $identityProviderName `
-MetadataUrl $identityProviderMetadataEndpoint `
-MonitoringEnabled $true `
-AcceptanceTransformRules ([System.String]::Concat($acceptanceTransformRules))
$relyingParty = Get-AdfsRelyingPartyTrust -Name $tenantRelyingPartyName
if ($relyingParty)
{
Write-Verbose -Message "Removing existing relying party $tenantRelyingPartyName"
Remove-AdfsRelyingPartyTrust -TargetName $tenantRelyingPartyName
}
Write-Verbose -Message "Creating relying party $tenantRelyingPartyName"
$transformationRules = (
"@RuleTemplate = ""PassThroughClaims"" @RuleName = ""UPN"" c:[Type == ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn""] => issue(claim = c);",
"@RuleTemplate = ""PassThroughClaims"" @RuleName = ""Group"" c:[Type == ""http://schemas.xmlsoap.org/claims/Group""] => issue(claim = c);",
"@RuleTemplate = ""PassThroughClaims"" @RuleName = ""Name"" c:[Type == ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name""] => issue(claim = c);",
"@RuleTemplate = ""PassThroughClaims"" @RuleName = ""DisplayName"" c:[Type == ""http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname""] => issue(claim = c);")
$issuanceRules = (
"=> issue(Type = ""http://schemas.microsoft.com/authorization/claims/permit"", Value = ""true"");")
$impersonationRules = (
"c:[Type == ""http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid"", Issuer =~""^(AD AUTHORITY|SELF AUTHORITY|LOCAL AUTHORITY)$"" ] => issue(store=""_ProxyCredentialStore"", types=(""http://schemas.microsoft.com/authorization/claims/permit""),query=""isProxySid({0})"", param=c.Value );c:[Type == ""http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid"", Issuer =~ ""^(AD AUTHORITY|SELF AUTHORITY|LOCAL AUTHORITY)$"" ] => issue(store=""_ProxyCredentialStore"",types=(""http://schemas.microsoft.com/authorization/claims/permit""),query=""isProxySid({0})"", param=c.Value );c:[Type == ""http://schemas.microsoft.com/ws/2008/06/identity/claims/proxytrustid"", Issuer =~ ""^SELF AUTHORITY$"" ] => issue(store=""_ProxyCredentialStore"",types=(""http://schemas.microsoft.com/authorization/claims/permit""),query=""isProxyTrustProvisioned({0})"", param=c.Value );")
# -MetadataUrl $tenantRelyingPartyMetadataEndpoint `
Add-AdfsRelyingPartyTrust `
-Enabled $true `
-Name $tenantRelyingPartyName `
-MetadataUrl $tenantRelyingPartyMetadataEndpoint `
-EnableJWT $true `
-AllowedClientTypes None `
-ClaimsProviderName $identityProviderName `
-IssuanceTransformRules ([System.String]::Concat($transformationRules)) `
-IssuanceAuthorizationRules ([System.String]::Concat($issuanceRules)) `
-ImpersonationAuthorizationRules ([System.String]::Concat($impersonationRules))
if($adminRelyingPartyMetadataEndpoint)
{
Add-AdfsRelyingPartyTrust `
-Enabled $true `
-Name $adminRelyingPartyName `
-MetadataUrl $adminRelyingPartyMetadataEndpoint `
-EnableJWT $true `
-AllowedClientTypes None `
-ClaimsProviderName $identityProviderName `
-IssuanceTransformRules ([System.String]::Concat($transformationRules)) `
-IssuanceAuthorizationRules ([System.String]::Concat($issuanceRules)) `
-ImpersonationAuthorizationRules ([System.String]::Concat($impersonationRules))
}
}
finally
{
[Net.ServicePointManager]::ServerCertificateValidationCallback = $OriginalServerCertificateValidationCallback
}
Example shown below:
Configure Admin and Tenant portal to use ADFS for authentication
Run following PowerShell in Azure Pack machine
- Start PowerShell as Administrator and run following commands
# WAP database conection information
$dbServer = 'wapdb'
$dbpassword='xxxxxxxxx!'
$portalConfigStoreConnectionString = [string]::Format('Data Source={0};Initial Catalog=Microsoft.MgmtSvc.PortalConfigStore;User ID=sa;Password={1}', $dbServer, $dbPassword)
# Configure tenant site to use Azure AD (thru ADFS)
Set-MgmtSvcRelyingPartySettings -Target Tenant -MetadataEndpoint https://adfs.contosocloud.com/FederationMetadata/2007-06/FederationMetadata.xml -DisableCertificateValidation -ConnectionString $portalConfigStoreConnectionString
# Configure admin site to use Azure AD (thru ADFS). Only if you like to configure Admin site with Azure AD
Set-MgmtSvcRelyingPartySettings -Target Admin -MetadataEndpoint https://adfs.contosocloud.com/FederationMetadata/2007-06/FederationMetadata.xml -DisableCertificateValidation -ConnectionString $portalConfigStoreConnectionString