Hero Banner

Secure Application Model

Learn and ask questions on how to implement secure application model

Reply
Level 1 Contributor

Connect-AzureAD to Other Tenants with Secure Application Model

Hello! Is it possible to use Connect-AzureAD to connect to other tenants using the secure application model? Connect-AzureAD goes through for me, but when attempting to run something like Get-AzureADUser, I get the following error:

get-azureaduser : Error occurred while executing GetUsers
Code: Request_BadRequest
Message: Invalid domain name in the request url.
RequestId: 84f9ac40-c6cb-4a58-beaf-b69dd1038b5e
DateTimeStamp: Sun, 21 Jul 2019 21:18:23 GMT
HttpStatusCode: BadRequest
HttpStatusDescription: Bad Request
HttpResponseStatus: Completed
At line:1 char:1
+ get-azureaduser
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-AzureADUser], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.AzureAD16.Client.ApiException,Microsoft.Open.AzureAD16.PowerShell.GetUser

Thanks in advance!

10 REPLIES 10
Microsoft

Re: Connect-AzureAD to Other Tenants with Secure Application Model

@ashin it possible, however, you need to be sure your Azure AD application is setup correctly. When up setup everything did you follow the guidance available here


Isaiah Williams
Cloud Technology Strategist | US – One Commercial Partner
Level 2 Contributor

Re: Connect-AzureAD to Other Tenants with Secure Application Model

Hi @idwilliams 

I am having the same problem. I believe my App is set up correctly (is there a way to confirm?) I followed: https://github.com/microsoft/Partner-Center-PowerShell#Native-App

 

I am able to use it with AppPlusUser rights to connect to the Partner Center and access Subscription and Licensing info.

 

I can also use it with the older ver 1 Msol/MS Online cmdlets to access Other Tenants, more or less as per:

https://docs.microsoft.com/en-us/powershell/partnercenter/multi-factor-auth?view=partnercenterps-1.5

 

After getting the RefreshToken, AppId, AppSecret, then New-PartnerAccessToken and Connect-PartnerCenter. I get the aadGraph and graph tokens. I can then use Connect-MsolService to connect to my tenancy, then Get-MsolPartnerContract to get a list of my Client/Customers, and use commands such as Get-MsolUser -TenantId <someClientTenantId> -- that works.

 

But if I use Connect-AzureAD instead, that will connect to MY Tenancy, and I can use Get-AzureAdContract to see my Clients/Customers. BUT... I can't work out how to use Connect-AzureAD again to connect to the CLIENT tenancy, whatever I do may work, but then Get-AzureAdUser returns as above: 

Get-AzureADUser : Error occurred while executing GetUsers
Code: Request_BadRequest
Message: Invalid domain name in the request url.

 

How can we use the new MFA-enabled Secure Application Model to connect to our client/customer AzureAD Tenancies and use the AzureAD cmdlets? (not the older, deprecated Msol ones). 

 

Do you have an example of this working? Thanks so much,

   -Saul

Level 2 Contributor

Re: Connect-AzureAD to Other Tenants with Secure Application Model

Has anyone worked this out with the AzureAD module / Delegated Admin / Secure App Module / MFA?

 

I just updated to the latest versions of AzureAD and PartnerCenter modules and the same problem: I can connect to PartnerCenter, get an AccessToken from a RefreshToken and connect to OUR (partner) AzureAD, then get a list of all our CLIENTS (using Get-AzureADContract) but I CANNOT connect to the client's AzureAD. No matter what I try for the Connect-AzureAD I can't connect to their tenant. I get the Request_BadRequest for any other AzureAD cmdlets.

 

Using older MsOnline module works (Get-MsolUser).

 

@daokeefe This is the issue I mentioned in the other thread. So when MS fixes the Exch Online PowerShell module to support the Secure App Model I hope they also fix this as I've already migrated all my scripts using Delegated Admin from Msol to AzureAD!

 

Thanks,

   --Saul

 

 

Microsoft

Re: Connect-AzureAD to Other Tenants with Secure Application Model

@ashin and @sansbacher when you connect using the Azure AD PowerShell module you will need to specify the tenant where you to connect. The following code snippet should help.

 

$credential = Get-Credential
$refreshToken = 'Your-Refresh-Token-Value'

$aadGraphToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://graph.windows.net -Credential $credential -TenantId 'xxxx-xxxx-xxxx-xxxx'
$graphToken =  New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://graph.microsoft.com -Credential $credential -TenantId 'xxxx-xxxx-xxxx-xxxx'

Connect-AzureAD -AadAccessToken $aadGraphToken.AccessToken -AccountId 'user@contoso.com' -MsAccessToken $graphToken.AccessToken -TenantId 'xxxx-xxxx-xxxx-xxxx'

Note that xxxx-xxxx-xxxx-xxxx should be the customer identifier where you want to connect.


Isaiah Williams
Cloud Technology Strategist | US – One Commercial Partner
Level 2 Contributor

Re: Connect-AzureAD to Other Tenants with Secure Application Model

Thanks @idwilliams , unfortunately I still cannot connect with AzureAD using this method - unless I'm missing something (or you're missing the Connect-PartnerCenter step). 

 

When I try your method and then call Get-AzureADUser I get:

Get-AzureADUser : Error occurred while executing GetUsers
Code: Authorization_IdentityNotFound
Message: The identity of the calling application could not be established.

 

I did what you suggested: 

Get-Credential # for this I used the NativeApp ID and the SharedSecret (which normally allows AppPlusUser access when it works)

$refreshToken   # I used a known working Refresh_Token

-TenantId    # for all 3 I used a confirmed Tenant / Microsoft ID of a client in our CSP Partner Center

-AccountId   # for this I used the username@domain.com in OUR tenant that has Account Admin permissions in the Partner Center that I used for the consent process.

[Is all that correct?]

 

And it didn't work. I also tried calling Connect-PartnerCenter but I get "Unauthorized access".

 

What I want to do: connect to the Partner Center, get a list of all Contracts/Clients and then connect to THEIR tenants (using Delegated Admin) to do stuff for each client. 

 

This works if I use commands similar to what you provided, but the -TenatID must be MY (partner) tenantID, and then use Connect-MsolService (with the aadGraph and MsGraph Tokens). I can then use Get-MsolUser -all -TenantId 'tenant-id-of-CLIENT-account'. 

 

But trying to do something similar with the AzureAD module doesn't work.  (but it does work if NOT using the Secure App Model, if I just use regular Delegated Admin).

 

Do you have any further suggestions? Thanks so much!

Level 2 Contributor

Re: Connect-AzureAD to Other Tenants with Secure Application Model

Has anyone had any luck with this? Any word from Microsoft? @idwilliams or @daokeefe ??

Highlighted
Level 2 Contributor

Re: Connect-AzureAD to Other Tenants with Secure Application Model

Did you guys ever get an answer to this?

I have hit the same stumbling block.

 

This implementation of the Secure App Model for Powershell has been an absolute disgrace and Microsoft should be ashamed of the awful service they are providing to their partners.

 

1 and a half months and no answer. Disgusting.

Community Manager

Re: Connect-AzureAD to Other Tenants with Secure Application Model

Hi @idwilliams 

 

Thank you for adding your input above!

 

There is a different way to solve this problem? Or at least could you please direct us to someone who can provide a solution on this matter?

 

Thank you!

Mihai

Microsoft

Re: Connect-AzureAD to Other Tenants with Secure Application Model

Alternatively to this community - If you need 1:1 technical advisory guidance on how to work with the secure app model, you can always contact askpts@microsoft.com when you are Partner with Silver or Gold competency level to get technical advice - or contact your SAM (Service account manager) when you have an ASfP contract to raise a cloud consult. Then a Partner Consultant can work with you on how to do management in the respective scenarios. 

 

Also there were quite a lot updates in the documentation in the meantime, so I generally recommend to take a look (Don't know if it solves any of the specific issues you see though):

https://docs.microsoft.com/en-us/partner-center/develop/enable-secure-app-model and updates to the powershell modules: 

https://docs.microsoft.com/en-us/powershell/partnercenter/multi-factor-auth?view=partnercenterps-2.0 

 

Also Isaiah Williams has published a few more more lab-oriented guides on his blog in the same: https://docs.isaiahwilliams.dev/articles/partner-security-requirements.html

Microsoft

Re: Connect-AzureAD to Other Tenants with Secure Application Model

You will receive this error if you have not configured the Azure AD application to available to all organizational directories and if it has not been configured for pre-consent. You can use the following PowerShell code to create an Azure AD application that will work 

 

<#
    .SYNOPSIS
        This script will create the require Azure AD application.
    .EXAMPLE
        .\Create-AzureADApplication.ps1 -ConfigurePreconsent -DisplayName "Partner Center Web App"

        .\Create-AzureADApplication.ps1 -ConfigurePreconsent -DisplayName "Partner Center Web App" -TenantId eb210c1e-b697-4c06-b4e3-8b104c226b9a

        .\Create-AzureADApplication.ps1 -ConfigurePreconsent -DisplayName "Partner Center Web App" -TenantId tenant01.onmicrosoft.com
    .PARAMETER ConfigurePreconsent
        Flag indicating whether or not the Azure AD application should be configured for preconsent.
    .PARAMETER DisplayName
        Display name for the Azure AD application that will be created.
    .PARAMETER TenantId
        [OPTIONAL] The domain or tenant identifier for the Azure AD tenant that should be utilized to create the various resources.
#>

Param
(
    [Parameter(Mandatory = $true)]
    [switch]$ConfigurePreconsent,
    [Parameter(Mandatory = $true)]
    [string]$DisplayName,
    [Parameter(Mandatory = $false)]
    [string]$TenantId
)

$ErrorActionPreference = "Stop"

# Check if the Azure AD PowerShell module has already been loaded.
if ( ! ( Get-Module AzureAD ) ) {
    # Check if the Azure AD PowerShell module is installed.
    if ( Get-Module -ListAvailable -Name AzureAD ) {
        # The Azure AD PowerShell module is not load and it is installed. This module
        # must be loaded for other operations performed by this script.
        Write-Host -ForegroundColor Green "Loading the Azure AD PowerShell module..."
        Import-Module AzureAD
    } else {
        Install-Module AzureAD
    }
}

try {
    Write-Host -ForegroundColor Green "When prompted please enter the appropriate credentials..."

    if([string]::IsNullOrEmpty($TenantId)) {
        Connect-AzureAD | Out-Null

        $TenantId = $(Get-AzureADTenantDetail).ObjectId
    } else {
        Connect-AzureAD -TenantId $TenantId | Out-Null
    }
} catch [Microsoft.Azure.Common.Authentication.AadAuthenticationCanceledException] {
    # The authentication attempt was canceled by the end-user. Execution of the script should be halted.
    Write-Host -ForegroundColor Yellow "The authentication attempt was canceled. Execution of the script will be halted..."
    Exit
} catch {
    # An unexpected error has occurred. The end-user should be notified so that the appropriate action can be taken.
    Write-Error "An unexpected error has occurred. Please review the following error message and try again." `
        "$($Error[0].Exception)"
}

$adAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
    ResourceAppId = "00000002-0000-0000-c000-000000000000";
    ResourceAccess =
    [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
        Id = "5778995a-e1bf-45b8-affa-663a9f3f4d04";
        Type = "Role"},
    [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
        Id = "a42657d6-7f20-40e3-b6f0-cee03008a62a";
        Type = "Scope"},
    [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
        Id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6";
        Type = "Scope"}
}

$graphAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
    ResourceAppId = "00000003-0000-0000-c000-000000000000";
    ResourceAccess =
        [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
            Id = "bf394140-e372-4bf9-a898-299cfc7564e5";
            Type = "Role"},
        [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
            Id = "7ab1d382-f21e-4acd-a863-ba3e13f7da61";
            Type = "Role"}
}

$partnerCenterAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
    ResourceAppId = "fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd";
    ResourceAccess =
        [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
            Id = "1cebfa2a-fb4d-419e-b5f9-839b4383e05a";
            Type = "Scope"}
}

$SessionInfo = Get-AzureADCurrentSessionInfo

Write-Host -ForegroundColor Green "Creating the Azure AD application and related resources..."

$app = New-AzureADApplication -AvailableToOtherTenants $true -DisplayName $DisplayName -IdentifierUris "https://$($SessionInfo.TenantDomain)/$((New-Guid).ToString())" -RequiredResourceAccess $adAppAccess, $graphAppAccess, $partnerCenterAppAccess -ReplyUrls @("urn:ietf:wg:oauth:2.0:oob")
$password = New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId
$spn = New-AzureADServicePrincipal -AppId $app.AppId -DisplayName $DisplayName

if($ConfigurePreconsent) {
    $adminAgentsGroup = Get-AzureADGroup -Filter "DisplayName eq 'AdminAgents'"
    Add-AzureADGroupMember -ObjectId $adminAgentsGroup.ObjectId -RefObjectId $spn.ObjectId
}

Write-Host "ApplicationId       = $($app.AppId)"
Write-Host "ApplicationSecret   = $($password.Value)"

Isaiah Williams
Cloud Technology Strategist | US – One Commercial Partner