How to automate URL navigation and code retrieval for creating a new PAT in Azure DevOps pipeline?

  Kiến thức lập trình

I’m working on an Azure DevOps pipeline that needs to create a new Personal Access Token (PAT) using a service principal. The process requires obtaining an authorization code by navigating to a specific URL, which the user must manually open in a browser. After the user authenticates, they are redirected to a new URL containing the authorization code as a query parameter. The user then needs to manually copy this code and input it back into the pipeline.

… like this In the browser it looks like an authorization code.

http://localhost:5000/getAToken?code=0.A1111111________________________________111111111111111111111IcQ&state=12345&session_state=bdd1111-1111-1111-9059-1111111111111111#

Here’s what the relevant part of my script looks like:

get_auth_code() {
  local authorize_url="https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=http://localhost:5000/getAToken&response_mode=query&resource=YOUR_RESOURCE_ID&state=12345"
  
  echo "Please open this URL in a browser and complete the authentication:"
  echo "$authorize_url"
  echo "After authentication, you will be redirected. Copy the entire URL of the page you are redirected to."
  
  read -p "Paste the redirected URL here: " redirected_url
  
  local auth_code=$(echo "$redirected_url" | sed -n 's/.*code=([^&]*).*/1/p')
  echo "$auth_code"
}

However, when running the pipeline, I receive the following log output while waiting for user input:

++ get_auth_code
++ local 'authorize_url=https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=http://localhost:5000/getAToken&response_mode=query&resource=YOUR_RESOURCE_ID&state=12345'
++ echo 'Please open this URL in a browser and complete the authentication:'
++ echo 'https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=http://localhost:5000/getAToken&response_mode=query&resource=YOUR_RESOURCE_ID&state=12345'
++ echo 'After authentication, you will be redirected. Copy the entire URL of the page you are redirected to.'
++ read -p 'Paste the redirected URL here: ' redirected_url
##[error]The Operation will be canceled. The next steps may not contain expected logs.
##[error]The operation was canceled.

One key challenge is that there is no way to interact directly with the pipeline’s runtime environment. This means I can’t manually input the authorization code during the pipeline execution, which disrupts the automation process.

Given this limitation, I need to automate the following steps within the pipeline:

Automatically navigate to the generated URL.
Retrieve the authorization code from the redirected URL.
Use this code to create a new PAT.
Furthermore, once the PAT is generated, I need to store it securely in Azure Key Vault (AKV) as a secret. Is there a way to automate this entire process within Azure DevOps pipelines? Or, if full automation isn’t possible, are there any best practices or alternative approaches to streamline this process as much as possible?

Here is an example of how I can achieve a similar process manually using a script in Ubuntu:

# Function for URL encoding
urlencode() {
    local string="${1}"
    local strlen=${#string}
    local encoded=""
    local pos c o

    for (( pos=0 ; pos<strlen ; pos++ )); do
        c=${string:$pos:1}
        case "$c" in
            [-_.~a-zA-Z0-9] ) o="${c}" ;;
            * )               printf -v o '%%%02x' "'$c"
        esac
        encoded+="${o}"
    done
    echo "${encoded}"
}

# Get bearer token
get_bearer_token() {
    local response=$(curl -s -X POST "https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/token" 
        -H "Content-Type: application/x-www-form-urlencoded" 
        -d "client_id=$CLIENT_ID" 
        -d "resource=YOUR_RESOURCE_ID" 
        -d "grant_type=password" 
        -d "client_secret=$CLIENT_SECRET" 
        -d "username=$USERNAME" 
        -d "password=$PASSWORD")

    echo "$response" | jq -r '.access_token'
}

# Generate authorization URL
generate_auth_url() {
    local encoded_redirect_uri=$(urlencode "$REDIRECT_URI")
    local encoded_scope=$(urlencode "$SCOPE")
    echo "https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/authorize?client_id=$CLIENT_ID&response_type=code&redirect_uri=$encoded_redirect_uri&response_mode=query&scope=$encoded_scope&state=12345"
}

# Create PAT using Bearer Token
create_pat() {
    local bearer_token="$1"
    local pat_name="new_token$(date +'%d%m%Y')"
    local expiration_date=$(date -u -d "+30 days" "+%Y-%m-%dT%H:%M:%S.000Z")
    
    local response=$(curl -s -X POST "https://vssps.dev.azure.com/YOUR_ORG/_apis/tokens/pats?api-version=7.1-preview.1" 
        -H "Content-Type: application/json" 
        -H "Authorization: Bearer $bearer_token" 
        -d "{
            "displayName": "$pat_name",
            "validTo": "$expiration_date",
            "scope": "app_token",
            "allOrgs": false
        }")

    local display_name=$(echo "$response" | jq -r '.patToken.displayName')
    local valid_to=$(echo "$response" | jq -r '.patToken.validTo')
    local pat_token=$(echo "$response" | jq -r '.patToken.token')

    if [ -z "$pat_token" ] || [ "$pat_token" == "null" ]; then
        echo "Failed to create PAT. API response:"
        echo "$response" | jq '.'
        return 1
    fi

    echo "PAT created successfully"
    echo "Display Name: $display_name"
    echo "Valid To: $valid_to"
    echo "Token: $pat_token"
}

# Main process
bearer_token=$(get_bearer_token)
echo "Bearer Token:"
echo "$bearer_token"

auth_url=$(generate_auth_url)
echo "Authorization URL:"
echo "$auth_url"

read -p "Paste the redirect URL: " redirect_url

auth_code=$(echo "$redirect_url" | sed -n 's/.*code=([^&]*).*/1/p')
echo "Authorization code:"
echo "$auth_code"

pat=$(create_pat "$bearer_token")
if [ $? -eq 0 ]; then
    echo "Personal Access Token (PAT):"
    echo "$pat"
else
    echo "Failed to create PAT. Please check the output above for more details."
fi

Thank you!

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT