4

I am trying to get a jwt token from AAD using Powershell using Username/Password authentication.

I am writing a powershell script that will to call an API using a bearer token. What I have works if I copy & paste the token from an SPA that uses the API. I am looking for a way to retrieve the token from my powershell.

This looks really promising: https://github.com/Azure-Samples/active-directory-dotnet-native-headless/blob/master/TodoListClient/Program.cs

I feel like I'm smacking my head against a wall trying to create a 'UserPasswordCredential' object. Any clues to how I can do this would be super-helpful.

I have Add-Type-ed:
- Microsoft.IdentityModel.Clients.ActiveDirectory.dll
- Microsoft.IdentityModel.Clients.ActiveDirectory.platform.dll (adds nothing?)
- Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
- Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll

The docs page for 'UserPasswordCredential' : https://learn.microsoft.com/en-us/dotnet/api/microsoft.identitymodel.clients.activedirectory.userpasswordcredential
It should be in one of the first two dlls

This, under 'Constraints & Limitations', makes me think it may not actually be possible from powershell: http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/

Looking at the code below, the first acquire token succeeds, the second fails - possibly/probably because $cred is a UserCredential not a UserPasswordCredential.

Is is possible to do this with powershell?


Finally, on a totally different track, how do I find the values for redirectUri and resourceAppIdURI that my application needs? When I look in the AAD console, and browser to my Enterprise Application, I can find the AppId (which I can use as $clientId).
I'm not sure the redirectUri is strictly necessary for me as all I really want is the token, but I can have a good guess at what it should be. When I try to call the first AquireToken method (without $cred) using my app details, it fails with this message:

Exception calling "AcquireToken" with "4" argument(s): "AADSTS50001: The application named https://myappwithapi/Login was not found in the tenant named me.onmicrosoft.com.

Is it possible for me to find the require value for resourceAppIdURI by looking in my azure portal?
'https://myappwithapi/Login' is from my azure portal > enterprise apps > [app' > properties > HomepageUrl


code:

#setup
$TenantName = "mme.onmicrosoft.com"
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2" # Microsoft
$clientId = "03faf8db-..........................." #

$username = "[email protected]"
$password = Read-Host -AsSecureString -Prompt "Enter Password"


# add dlls
$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
$adalplatform = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.platform.dll"
[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null
[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null
[System.Reflection.Assembly]::LoadFrom($adalplatform) | Out-Null



#prep request
$redirectUri = "urn:ietf:wg:oauth:2.0:oob" # Microsoft
$resourceAppIdURI = "https://graph.windows.net"
$authority = "https://login.windows.net/$TenantName"
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority


# Get Token prompting for creds
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Always")
$authResult


# Get the cred
$cred = New-Object -TypeName 'Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential' -ArgumentList $username, $password
#$cred = New-Object -TypeName 'Microsoft.IdentityModel.Clients.ActiveDirectory.UserPassCredential' -ArgumentList $username, $password
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $cred)

$authResult
4
  • This is possible in Powershell. I've created multiple scripts that do this (using the different flavors of login methods, client credentials, app key or certificate). If you read all the documents Microsoft has about this topic you should also see HOW to get the specific AppID, set the redirect url etc (all the stuff needed). Since I'm not sure which type of login you're trying to achieve I can't post any of my samples. Commented Jan 3, 2018 at 7:08
  • Have you tried the Get-Credential cmdlet to prompt for id/password? Not a direct answer to your question but it might make your script a bit more friendly to the user. Commented Jan 3, 2018 at 15:41
  • Yep, Get-Credential gives me a PSCredential which $authContext.AcquireToken won't accept Commented Jan 4, 2018 at 0:41
  • @bluuf I feel like I have read all the document, my brain is melted. I want to use Username/Password to sign in. That appears to require a UserPasswordCredential which I can't make available to New-Object. I recognize this seems a pretty basic question, but I can't find any more details that don't effectively fall back to the TodoListClient example. Commented Jan 4, 2018 at 0:49

1 Answer 1

4

This post has more the one question in it.

Your base use case 'Using Powershell to get Azure AD Token (jwt)' is a common one and there are several samples and pre-built examples to leverage. For example:

https://github.com/pcgeek86/AzureADToken A PowerShell module that allows you to get a JSON Web Token (JWT) from Azure Active Directory (AAD).

https://gallery.technet.microsoft.com/Get-Azure-AD-Bearer-Token-37f3be03 This script acquires a bearer token that can be used to authenticate to the Azure Resource Manager API with tools such as Postman. It uses the Active Directory Authentication Library that is installed with the Azure SDK.

See if those two resources resolves your use base line use case.

As for this... "Is it possible for me to find the require value for resourceAppIdURI by looking in my azure portal?"

You can do this via a remote PowerShell logon to AzureAD. Install the AAD PowerShell module. https://learn.microsoft.com/en-us/powershell/azure/overview?view=azurermps-5.1.1 https://msdn.microsoft.com/en-us/library/dn135248(v=nav.70).aspx

Download and install MSOL. Sign in with the MSOL https://www.microsoft.com/en-US/download/details.aspx?id=39267 The Microsoft Online Services Sign-In Assistant provides end user sign-in capabilities

and use the built-in cmdlets to pull your information from your organization settings, and or hit the MSGraph API and query. https://learn.microsoft.com/en-us/powershell/azure/active-directory/install-adv2?view=azureadps-2.0 You can use the Azure Active Directory PowerShell Module Version for Graph for Azure AD administrative tasks

As for this one: "how do I find the values for redirectUri and resourceAppIdURI that my application needs?" This is in your app registration section of your portal. The developer team provide the redir uri not Azure. It's part of the registration process all else is generated by Azure App Reg process.

The app registration process is here and of course you are someone else had to register this app in AzureAD, and thus can retrieve it at any time.: https://blogs.msdn.microsoft.com/onenotedev/2015/04/30/register-your-application-in-azure-ad

Any registered apps and their details can be retrieved using...

Get-AzureADApplication
Get-AzureADApplication | Select -Property *
(Get-AzureADApplication).ReplyUrls
Get-AzureADApplication | Select -Property AppID, DisplayName,ReplyUrls

https://learn.microsoft.com/en-us/powershell/module/azuread/get-azureadapplication?view=azureadps-2.0

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, really good info there. When I call Get-AzureADApplication I get nothing. No errors, nothing. Same if I use -All $true or -Filter on Display or AppID... The `Connect-AzureAD' succeeded, the tenant Id and user are correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.