Can I use MFA app passwords with Azure oauth2.0 ROPC?

后端 未结 1 610
清歌不尽
清歌不尽 2021-01-17 05:31

In powershell we have a script that gets info from Azure REST API using Resource Owner Password Credentials.

https://docs.microsoft.com/bs-latn-ba/azure/active-direc

相关标签:
1条回答
  • 2021-01-17 06:19

    As far as I know, app password is used to complete MFA with the clients which do not support modern authentication. Now, you use ROPC OAuth flow. APP password does not support it.

    According to the situation, I suggest you finish MFA manually to get refresh token then we use refresh token to get access token and call API. Because MFA refresh token will not expire until you revoke it. Or you use OAuth 2.0 client credentials flow to get the access token. For example

    User refresh token

    1. Register Azure AD application

    2. Use OAuth 2.0 authorization code flow to complete MFA and get refresh token

    $Params = @{
        'client_id' = 'b0114608-677e-4eca-ae22-60c32e1782d9' 
        'redirect_URI' = 'https://www.baidu.com'
        'response_type'='code'
        'scope' = 'offline_access openid https://management.azure.com/user_impersonation'
    }
    $ClientSecret =''
    $TeantID = ''
    $Query = "?"; $Params.Keys | % {$Query+= "$($_)=$($Params.Item($_))&"} ; $Query = $Query.TrimEnd('&')
    
    
    $IE= new-object -ComObject "InternetExplorer.Application"
    $IE.Visible = $true
    $IE.navigate2("https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/authorize$Query")
    
    write-host "get authorization code"
    pause
    
    Add-Type -AssemblyName System.Web
    [System.Web.HttpUtility]::ParseQueryString(([uri] $IE.LocationURL).Query)['code']
    $Code = [System.Web.HttpUtility]::ParseQueryString(([uri] $IE.LocationURL).Query)['code']
    $IE.Quit()
    
    $TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body @{
        client_id     = $Params.client_id
        scope         = ''
        code          = $Code
        redirect_uri  = $Params.Redirect_URI
        grant_type    = 'authorization_code'
        client_secret = $ClientSecret
    }
    
    $TokenResult.refresh_token
    
    1. Get Access token and call the api
    $TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body @{
        client_id     = ''
        scope         = 'https://management.azure.com/user_impersonation'
        redirect_uri  = ''
        grant_type    = 'refresh_token'
        client_secret = ''
        refresh_token =''
    }
    
    
    
     Invoke-RestMethod -Method Get -Uri '' -Headers @{Authorization = "Bearer "+ $TokenResult.access_token}
    

    Use OAuth 2.0 client credentials flow

    $TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body @{
        client_id     = ''
        scope         = 'https://management.azure.com/.default'
        grant_type    = 'client_credentials'
        client_secret = ''
    
    }
    
     Invoke-RestMethod -Method Get -Uri '' -Headers @{Authorization = "Bearer "+ $TokenResult.access_token}
    

    Update According to your need, you can create a service principal and assign RABC role to the service principal. Then you can OAuth 2.0 client credentials flow to get access token and call Azure rest api. The detailed steps are as below

    1. Create a service principal and assign RABC role to the service principal
    Connect-AzAccount
    $password=''
    $credentials = New-Object Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential -Property @{ StartDate=Get-Date; EndDate=Get-Date -Year 2024; Password=$password'}
    $sp = New-AzAdServicePrincipal -DisplayName jimtest1 -PasswordCredential $credentials
    
    New-AzRoleAssignment -ApplicationId $sp.ApplicationId -RoleDefinitionName Owner
    
    1. Get access token
    # get access token
    $TeantID='hanxia.onmicrosoft.com'
    $TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body @{
        client_id     = $sp.ApplicationId # the application id of service principal
        scope         = 'https://management.azure.com/.default'
        grant_type    = 'client_credentials'
        client_secret = $password # you use it in step 1
    
    }
    
    1. Call Azure Rest API
    #list resource group
    $values =Invoke-RestMethod -Method Get -Uri "https://management.azure.com/subscriptions/e5b0fcfa-e859-43f3-8d84-5e5fe29f4c68/resourcegroups?api-version=2019-05-10" -Headers @{
    Authorization = "Bearer "+ $TokenResult.access_token
    ContentType = 'application/json'
    }
    

    For more details, please refer to

    https://docs.microsoft.com/en-us/powershell/azure/create-azure-service-principal-azureps?view=azps-2.7.0

    https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-api-authentication#get-app-only-access-token-for-azure-resource-manager

    0 讨论(0)
提交回复
热议问题