Acquire Authorization Token for Azure Function App from PowerShell - powershell

I've a problem getting token for my azure application
here is the code
function Get-Token
{
ipmo "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
ipmo "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
$clientId = "1b730954-1685-4b74-9bfd-dac224a7b894"
$redirectUri = "urn:ietf:wg:oauth:2.0:oob"
$resourceAppIdURI = "https://ios111.azurewebsites.net/"
$authority = "https://login.microsoftonline.com/common/"
$authContext = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]$authority
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")
$authResult.CreateAuthorizationHeader()
}
I receive the following error
Exception calling "AcquireToken" with "4" argument(s): "AADSTS65005:
Invalid resource. The client has requested access to a resource which
is not listed in the requested permissions in the client's application
registration. Client app ID: 1b730954-1685-4b74-9bfd-dac224a7b894.
Resource value from request: https://ios111.azurewebsites.net/.
Resource app ID: f4c1cc8d-629a-4c7e-836a-120ff078e664. List of valid
resources from app registration: .
However if i change the $resourceAppIdURI to
$resourceAppIdURI = "https://management.core.windows.net/"
It's all ok, and i'm authorized to access my application with received token (if i set Authorization header value to this token), but without roles claim which i define in application manifest for this user and which i want to check.
If i just access my function from browser, after login page redirected me back to a function, there is no a Authorization header specified by browser but ARRAffinity cookie and ClaimsPrincipal.Current.Claims in function context has correct roles claim. So, seems in case of PS, there JWT token acquired by .AcquireToken is deserialized to ClaimsPrincipal.Current without using internal web app logic.
Any ideas how to give PS client a permission to access my app ?
Thanks !

To Get Azuere App Token with the required roles, you need a ClientId and Secret, along with required permissions setup, if admin-consent is needed, you should click the 'Grant Permissions' button on the application properites in the Azure Portal.
Then, if all is set correct, you can get a token like this (with the roles included):
Example for the Microsoft Graph API
$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null
$TenantName = "tenant.onmicrosoft.com"
$ClientId = "d1245516-2bg3-1234-123d-7cd067ff66b4" # Your AppId (Just a sample)
$Secret = "H7dd+PejUddGhuuGYY234Xhhhjs7739iQn112317zg=" # Your App Key Secret (Just a sample)
$AuthId = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential($clientId,$secret)
$redirectUri = "urn:ietf:wg:oauth:2.0:oob"
$resourceAppIdURI = "https://graph.microsoft.com"
[uri]$authority = "https://login.windows.net/$TenantName/oauth2/authorize"
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
$Token = $authResult = $authContext.AcquireToken($resourceAppIdURI, $AuthId)
To Check the token you can use this JWT Token Decoder, to see if it has the required roles:
http://jwt.calebb.net/

Solved !
Thank for the help you guys !
Actually, i had to register native azure application, give it access for my WebApp and use this appId as the clientId in the script above. Using "1b730954-1685-4b74-9bfd-dac224a7b894" as Well Known PowerShell clientId probably possible for standard MS app, but there no way you can grand PS access for you app, at least not from azure portal.
Here is the link https://markscholman.com/2016/08/consuming-azure-api-app-azure-ad-authentication-using-powershell/ with step by step explanation given by WayneYang-MSFT

Related

Cannot call Graph API using delegated permissions in PowerShell

I have an Azure App Registration setup as below:
Not shown: two redirect URIs for https://login.microsoftonline.com/common/oauth2/nativeclient (which I believe is needed for auth code flows if using PowerShell?) and https://MYDEVSERVER
We have a web API that can correctly access Graph against this App Registration by using a hybrid on-behalf-of flow and IConfidentialClientApplication, along with a bootstrap token provided by an Office add-in.
The creation of this App Registration is actually done by a PowerShell script, and I want to add a feature that will try to login as the script user to make a test Graph API call (against the /me endpoint) to make sure it is setup correctly. The script can ensure that the App Registration is granted admin consent for the Graph API permissions so the script user does not have to provide consent.
From what I understand, the authorization code flow can be used to test these delegated permissions. However, I've tried two approaches with different results as below using the MSAL module to get the token and then use that token in the authorization header for a Graph call to simply return details about the logged in user via the /me endpoint:
If I don't pass a client secret to the Get-MsalToken cmdlet, I do get a login prompt but Get-MsalToken always returns the error 'AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'
If I do provide a client_secret, I do NOT get the login prompt and can successfully get a token, but the Graph call fails saying that the /me request is only valid with delegated authentication flow. Which makes sense because we need a user context.
So I'm stuck - I can't use the user context with the interactive login without it expecting a client secret that if I do use is using a different flow that's not supporting delegated permissions. What am I doing wrong? Or do I need to use a completely different authentication flow?
Does the fact that the App Registration is designed to handle SSO with Office web add-ins have anything to do with it? Meaning, I have a scope (e.g. api://MYWEBSERVER/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/access_as_user, as used by the add-in manifests for purposes of issuing a bootstrap token from the Office JS library to our Web API) and a list of authorized client applications (Office apps) in the 'Expose an API' section. I'm wondering if only those applications are authorized, and not the PowerShell script...
I've also seen some suggestions about using the device code flow and I'm wondering if I'm missing a step to get a refresh token (as demonstrated here but I can't get that example to work either using a client secret (I can't figure out the proper Get-MsalToken parameter combination).
$graphEndPointUrl = "https://graph.microsoft.com/v1.0/me"
$connectionDetails = #{
'TenantId' = $tenantId #Set variable to your own value
'ClientId' = $clientId #Set variable to your own value
'Scopes' = 'https://graph.microsoft.com/.default'
}
#Using the above information, it throws this error on Invoke-RestMethod:
#ERROR: "{"error":"invalid_client","error_description":"AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
#"error_codes":[7000218]
#"error_uri":"https://login.microsoftonline.com/error?code=7000218"}"
$connectionDetails = #{
'TenantId' = $tenantId #Set variable to your own value
'ClientId' = $clientId #Set variable to your own value
'ClientSecret' = $clientSecret | ConvertTo-SecureString -AsPlainText -Force #Set $clientSecret variable to your own value
'Scopes' = 'https://graph.microsoft.com/.default'
}
#Using the above information, it throws this error on Invoke-RestMethod:
#ERROR: "{"error":{"code":"BadRequest","message":"/me request is only valid with delegated authentication flow."
Import-Module MSAL.PS
try {
$myAccessToken = Get-MsalToken #connectionDetails
Write-Host $myAccessToken.AccessToken
$authHeader = #{
'Authorization' = $myAccessToken.CreateAuthorizationHeader()
}
$response = Invoke-RestMethod -Uri $graphEndPointUrl -Headers $authHeader
#Error thrown below
if ($null -eq $response) {
Write-Error "An unexpected error occurred making a test Graph API call to the $($graphEndPointUrl) endpoint" -ForegroundColor Red
}
else {
Write-Host "The test Graph API call to the $($graphEndPointUrl) endpoint was successful!"
}
}
catch {
$result = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($result)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
$errorObj = ConvertFrom-Json -InputObject $responseBody
Write-Host "An unexpected error occurred making a test Graph API call to the $($graphEndPointUrl) endpoint: $($errorObj.error.message)"
}
Update
Everything you need I believe is written in this Microsoft article - https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
I noticed a key difference in the tutorial you referenced and your setup, thats the ID Token that is used with the hybrid setup, you can read more about it in the MS guide, check response_mode .
So principal goes as follow > You get an authorization code > use that code to generate your access and refresh tokens > then you can use different API calls with the Access token in the header.
As for your code, here are the things that are missing or are not correctly implemented.
You are missing the RedirectUri param. Make sure the URL is exact I have just put https://localhost as an example.
$connectionDetails = #{
'TenantId' = $tenantId #Set variable to your own value
'ClientId' = $clientId #Set variable to your own value
'ClientSecret' = $clientSecret | ConvertTo-SecureString -AsPlainText -Force #Set $clientSecret variable to your own value
'Scopes' = 'https://graph.microsoft.com/.default'
'RedirectUri' = 'https://localhost'
}
Your header is not implementing the Authorization properly. Check out the example from the tutorial
$myAuthMethods = (Invoke-RestMethod -Headers #{Authorization = "Bearer $($myAccessToken.AccessToken)" } `
-Uri "https://graph.microsoft.com/beta/me/authentication/methods" `
-Method Get).value
$myAuthMethods
The header have the following structure, where the word Bearer is before the token.
$header = #{
"Authorization" = "Bearer $($myAccessToken.AccessToken)"
}
Make sure you have the access token $myAccessToken.AccessToken in the header.
At that point, you should at least get a different error if request does not proceed.
The issue is that an additional "Mobile and desktop applications" platform needs to be added to the App Registration on the Authentication page (with "https://login.microsoftonline.com/common/oauth2/nativeclient" as a Redirect URI), as it only has a web platform currently. Then Get-MsalToken works without a client Id:
$myAccessToken = Get-MsalToken -ClientId $clientID -TenantId $tenantId -Interactive -Scopes 'https://graph.microsoft.com/.default' -RedirectUri 'https://login.microsoftonline.com/common/oauth2/nativeclient'
However, an additional request is needed to get a refresh token and use that for the Graph call:
$myAccessToken = Get-MsalToken -ClientId $clientID -TenantId $tenantId -Silent

Powershell: Get-MsalToken error AADSTS7000218

Running the following Powershell command
$tokenresponse = Get-MsalToken -ClientId $clientID -TenantId $tenantID -Interactive -RedirectUri "http://localhost"
gives me the error:
AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
All solutions I found are pointing to the direction, that in the Azure Protal I should enable "Allow public client flows" but this setting is enabled. Any idea how I can get the token (I would need to get a token for delegated permissions)
I know this is an old question, but my answer below might help someone in the future. I ran into this same problem today and the way to fix it was by correcting the configuration on the App Registration. The solution was quite simple. I just had to set up Authentication to the right platform: "Mobile and desktop applications". Instead of Web or SPA.
To test it, get your tenant id and application (client) id, and pass it to the Get-MsalToken commandlet like below. The login page should pop-up, including any MFA dialogs (if MFA is configured).
$tenant_id = "00000000-0000-0000-0000-0000000000000"
$client_id = "00000000-0000-0000-0000-0000000000000"
$authParams = #{
ClientId = $client_id
TenantId = $tenant_id
Interactive = $true
}
$auth = Get-MsalToken #authParams
$auth

Authenticate via OAuth with App Secret to EWS in PowerShell

I am seeking the proper PowerShell code for how to authenticate to EWS via OAuth with only an app secret instead of a username and password. I have the app registration set with full_access_as_app permissions. The use case is the application runs is a daemon that sends emails based on supplied to and from addresses. The from users are remote users do not authenticate into the system so process that handles sending the emails cannot authenticate as them via OAuth.
I found this it was helpful so I assume only the part about getting the token needs to be changed: Powershell, EWS, OAuth2, and automation
There are a few different approaches you could take eg if you used the MSAL library which is different from ADAL which the script you pointed is using then you could do something like.
$ClientId = "9d5d77a6-xxxx-473e-8931-958f15f1a96b"
$MailboxName = "gscales#domain.com"
$RedirectUri = "msal9d5d77a6-fe09-473e-8931-958f15f1a96b://auth"
$ClientSecret = "xxx";
$Scope = "https://outlook.office365.com/.default"
$TenantId = (Invoke-WebRequest https://login.windows.net/datarumble.com/v2.0/.well-known/openid-configuration | ConvertFrom-Json).token_endpoint.Split('/')[3]
$app = [Microsoft.Identity.Client.ConfidentialClientApplicationBuilder]::Create($ClientId).WithClientSecret($ClientSecret).WithTenantId($TenantId).WithRedirectUri($RedirectUri).Build()
$Scopes = New-Object System.Collections.Generic.List[string]
$Scopes.Add($Scope)
$TokenResult = $app.AcquireTokenForClient($Scopes).ExecuteAsync().Result;

Authenticate to an Azure webapp through a second app registration using an Azure user token?

Working scenario
I have an Azure web application (https://www.contoso.com) to which I want to authenticate against and perform web call on.
I want to authenticate myself using Connect-AzAccount and make calls to it using my own identity.
I use the following code with success to obtain a valid token and call the application.
#Authenticate as myself or a sevice principal
Connect-AzAccount -Tenant 'a736bac3-c259-450f-90a4-f7d5bd7c4c78'
# App registration ID for Contoso
$ResourceUri = '24114488-8c26-4e87-8f71-90de62f5a8aa'
$Context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, $ResourceUri).AccessToken
$Headers = #{Headers = #{Authorization = "Bearer $token" } }
Invoke-RestMethod -Method Get -uri 'https://Contoso.com/module/Something' #Headers
That being said, the application itself does not implement forced user & groups assignment.
Instead, everybody can connect to it (by design).
The problematic
The solution presented above requires me to add Powershell Azure (1950a258-227b-4e31-a9cf-717495945fc2) in the list of Authorized client application to enable this scenario. By doing this operation, anybody in my directory can now technically make calls to the website, which is not desired.
Desired Scenario
Because user assignment is not enforced, I removed the Powershell Azure client from the main app and instead created a second App Registration for which I authorized the PS AZ client and added an API permission so it had access to the main App. The idea is that I can require user assignement for the second app registration and therefore limit the user that can make these kind of calls.
Initial (working) flow:
Connect-AzAccount authenticate the user
Code sample above is ran to obtain the token and call the app.
Desired flow
Connect-AzAccount authenticate the user
User connect through the client app registraion (new app) that has api permission to the main app.
User make calls to the main app.
Now, if I try to use my initial code sample with the Application Id of the second registration acting as a client ID, I get the following error
Invoke-RestMethod : {"code":401,"message":"IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not
match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'."}
At line:1 char:12
+ $result2 = Invoke-RestMethod -Method Get -uri 'https://Contoso.com/so...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExcept
ion
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I believe that this is because I am obtaining a token for the second app registration and trying to call the main app URL, which is not authorized through the token.
A "working" alternative to this problem would be to connect using Client_credentials as grant_type such as this:
function get-Bearer([string]$TenantID, [string]$ClientID, [string]$ClientSecret) {
$TokenEndpoint = "https://login.windows.net/{0}/oauth2/token" -f $TenantID
$Body = #{
'resource' = '24114488-8c26-4e87-8f71-90de62f5a8aa'
'client_id' = $ClientID
'grant_type' = 'client_credentials'
'client_secret' = $ClientSecret
}
$params = #{
ContentType = 'application/x-www-form-urlencoded'
Headers = #{'accept' = 'application/json' }
Body = $Body
Method = 'Post'
URI = $TokenEndpoint
}
$token = Invoke-RestMethod #params
Return "Bearer " + ($token.access_token).ToString()
}
If I do that, even though I can make calls to the main app. again but it is connected with the actual client app. and not using the user identity obtained through Connect-AzAccount (for which tokens can be generated through the initial sample)
I was also able to make it work with a password grant_type but this is not making use of my bearer token and is also invalidated by MFA enabled users.
All insights are welcome.
References
Microsoft Identity platform documentation - v2-oauth2-on-behalf-of-flow
(digging around the application flow to try and get something working)
Application app ids, not object ids, should be used as resources identifiers. Keep getting tokens using the first application (24114488-8c26-4e87-8f71-90de62f5a8aa) as resource/audience (using its application id uri) and the second application as client. Connect-Az will be out of the equation.
#Install the ADAL.PS package if it's not installed.
if(!(Get-Package adal.ps)) { Install-Package -Name adal.ps }
$authority = "https://login.windows.net/common/oauth2/authorize"
#this is the security and compliance center endpoint
$resourceUrl = "{first application id uri}"
#replace <redirect-uri>, with the Redirect URI from your Azure AD application registration.
$clientId = "{second application app id}"
$redirectUri = "<redirect-uri>"
$response = Get-ADALToken -Resource $resourceUrl -ClientId $clientId -RedirectUri $redirectUri -Authority $authority -PromptBehavior:Always
$response.AccessToken | clip
I finally succeeded in my attempt.
In case my initial question was confusing, I "simply" wanted to connect as myself on Web API B using an intermediary Web API A
The reason was that I could not implement control access on Web API B (it is a requirement that it is available for all users of the tenant) and I also could not add Powershell client ID to Web API B directly as this would have allowed everyone to obtain a token and make call to Web API B using Powershell.
Therefore, I needed the intermediary Web API A to allow Powershell client ID and provide a controlled / limited user access to Web API B
There is a flow in the Microsoft identity platform and Oauth 2.0 called On-Behal-Of flow which allow exactly that scenario.
Prerequisites
App Registration for Web API B
API Permission: Delegated permission to User.Read (Graph API)
Expose an API: add a User_Impersonation scope and the Application ID of Web API A in the authorized client ID
App Registration for Web API A
In Api Permissions, add the User_Impersonation scope of Web API B
From there, the following code will get you connected
Connect-AzAccount -TenantId '584e32bc-214f-4046-89e5-79b7bac9ae75'
$Params = #{
ClientId = '6788d279-fb83-4962-b371-445479875e0e'
ClientSecret = '16cc0f3d88cb4dd189fe6bf8e845982d'
resourceId = 'aeefa559-cb1c-41eb-ac5d-0bcb0bc01eaf'
Scope = 'https://graph.microsoft.com/user.read+offline_access'
}
function Get-AzCustomTokenOnBehalOf {
[CmdletBinding()]
param (
$ClientId,
$ClientSecret,
#Application ID of the target resource
$ResourceId,
$Scope
)
# Get Token For WebApp A $TenantId
$Context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$IntermediaryToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, $ClientId).AccessToken
$TokenUri = "https://login.microsoftonline.com/$($Context.Tenant.Id)/oauth2/token"
$FinalToken = Invoke-RestMethod -Uri $TokenUri -Method Post -Body #{
grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
resource = $ResourceId
client_id = $ClientId
client_secret = $ClientSecret
assertion = $IntermediaryToken
scope = $Scope
requested_token_use = 'on_behalf_of'
}
return $FinalToken
}
$Token = Get-AzCustomTokenOnBehalOf #Params
$Headers = #{Headers = #{Authorization = "bearer $($Token.access_token)" } }
$MYsite = Invoke-RestMethod -Method Get -uri 'https://SomeWebsite.com/' #Headers
Additional considerations
This scenario do require a client secret (This is the one I demonstratedO or a client certificate in order to work.
It is also subject to some limitations defined in the reference documentation and might not be suitable to all scenarios.
References:
Microsoft identity platform and OAuth 2.0 On-Behalf-Of flow

Using Powershell to get Azure AD Token (jwt)

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 = "me#me.onmicrosoft.com"
$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
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