Home > Jamf Pro, Jamf Pro Classic API, Scripting > Basic Authentication authentication now disabled for the Jamf Pro Classic API as of Jamf Pro 11.5.0

Basic Authentication authentication now disabled for the Jamf Pro Classic API as of Jamf Pro 11.5.0

As a follow-up to my earlier post on Basic Authentication being deprecated for the Jamf Pro Classic API (first announced as part of the release of Jamf Pro 10.35.0), Jamf has disabled Basic Authentication support for the Jamf Pro Classic API as Jamf Pro 11.5.0.

One thing to note is that this change does not impact Cisco ISE integration, which also uses Basic Authentication.

For those looking now to transition away from Basic Authentication for connecting to the Jamf Pro Classic API, I’ve written a couple of shell script functions to assist with getting the bearer tokens now used for API authentication for the following categories:

For more details, please see below the jump.

Jamf Pro API clients:


#!/bin/bash
# If you choose to hardcode API information into the script, set one or more of the following values:
#
# The Jamf Pro URL
# An API client ID on the Jamf Pro server with sufficient API privileges
# The API client secret for the API client ID
# Set the Jamf Pro URL here if you want it hardcoded.
jamfpro_url=""
# Set the Jamf Pro API Client ID here if you want it hardcoded.
jamfpro_api_client_id=""
# Set the Jamf Pro API Client Secret here if you want it hardcoded.
jamfpro_api_client_secret=""
# If you do not want to hardcode API information into the script, you can also store
# these values in a ~/Library/Preferences/com.github.jamfpro-info.plist file.
#
# To create the file and set the values, run the following commands and substitute
# your own values where appropriate:
#
# To store the Jamf Pro URL in the plist file:
# defaults write com.github.jamfpro-info jamfpro_url https://jamf.pro.server.goes.here:port_number_goes_here
#
# To store the Jamf Pro API Client ID in the plist file:
# defaults write com.github.jamfpro-info jamfpro_api_client_id api_client_id_information_goes_here
#
# To store the Jamf Pro API Client Secret in the plist file:
# defaults write com.github.jamfpro-info jamfpro_api_client_secret api_client_secret_information_goes_here
#
# If the com.github.jamfpro-info.plist file is available, the script will read in the
# relevant information from the plist file.
if [[ -f "$HOME/Library/Preferences/com.github.jamfpro-info.plist" ]]; then
if [[ -z "$jamfpro_url" ]]; then
jamfpro_url=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_url)
fi
if [[ -z "$jamfpro_api_client_id" ]]; then
jamfpro_api_client_id=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_api_client_id)
fi
if [[ -z "$jamfpro_api_client_secret" ]]; then
jamfpro_api_client_secret=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_api_client_secret)
fi
fi
# If the Jamf Pro URL, the API Client ID or the API Client Secret aren't available
# otherwise, you will be prompted to enter the requested URL or API client credentials.
if [[ -z "$jamfpro_url" ]]; then
read -p "Please enter your Jamf Pro server URL : " jamfpro_url
fi
if [[ -z "$jamfpro_api_client_id" ]]; then
read -p "Please enter your Jamf Pro API client ID : " jamfpro_api_client_id
fi
if [[ -z "$jamfpro_api_client_secret" ]]; then
read -p "Please enter the API client secret for the $jamfpro_api_client_id API ID client: " -s jamfpro_api_client_secret
fi
echo ""
# Remove the trailing slash from the Jamf Pro URL if needed.
jamfpro_url=${jamfpro_url%%/}
GetJamfProAPIToken() {
# This function uses the API client ID and client ID secret to get a new bearer token for API authentication.
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
api_token=$(/usr/bin/curl -s -X POST "$jamfpro_url/api/oauth/token" –header 'Content-Type: application/x-www-form-urlencoded' –data-urlencode client_id="$jamfpro_api_client_id" –data-urlencode 'grant_type=client_credentials' –data-urlencode client_secret="$jamfpro_api_client_secret" | python -c 'import sys, json; print json.load(sys.stdin)["access_token"]')
else
api_token=$(/usr/bin/curl -s -X POST "$jamfpro_url/api/oauth/token" –header 'Content-Type: application/x-www-form-urlencoded' –data-urlencode client_id="$jamfpro_api_client_id" –data-urlencode 'grant_type=client_credentials' –data-urlencode client_secret="$jamfpro_api_client_secret" | plutil -extract access_token raw -)
fi
}
APITokenValidCheck() {
# Verify that API authentication is using a valid token by running an API command
# which displays the authorization details associated with the current API user.
# The API call will only return the HTTP status code.
api_authentication_check=$(/usr/bin/curl –write-out %{http_code} –silent –output /dev/null "${jamfpro_url}/api/v1/auth" –request GET –header "Authorization: Bearer ${api_token}")
}
GetJamfProAPIToken
APITokenValidCheck
echo "$api_authentication_check"
echo "$api_token"

Jamf Pro user accounts:


#!/bin/bash
# This script uses the Jamf Pro API to get an authentication token
# Set default exit code
exitCode=0
# Explicitly set initial value for the api_token variable to null:
api_token=""
# Explicitly set initial value for the token_expiration variable to null:
token_expiration=""
# If you choose to hardcode API information into the script, set one or more of the following values:
#
# The username for an account on the Jamf Pro server with sufficient API privileges
# The password for the account
# The Jamf Pro URL
# Set the Jamf Pro URL here if you want it hardcoded.
jamfpro_url=""
# Set the username here if you want it hardcoded.
jamfpro_user=""
# Set the password here if you want it hardcoded.
jamfpro_password=""
# Read the appropriate values from ~/Library/Preferences/com.github.jamfpro-info.plist
# if the file is available. To create the file, run the following commands:
#
# defaults write $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_url https://jamf.pro.server.here
# defaults write $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_user API_account_username_goes_here
# defaults write $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_password API_account_password_goes_here
#
if [[ -f "$HOME/Library/Preferences/com.github.jamfpro-info.plist" ]]; then
if [[ -z "$jamfpro_url" ]]; then
jamfpro_url=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_url)
fi
if [[ -z "$jamfpro_user" ]]; then
jamfpro_user=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_user)
fi
if [[ -z "$jamfpro_password" ]]; then
jamfpro_password=$(defaults read $HOME/Library/Preferences/com.github.jamfpro-info jamfpro_password)
fi
fi
# If the Jamf Pro URL, the account username or the account password aren't available
# otherwise, you will be prompted to enter the requested URL or account credentials.
if [[ -z "$jamfpro_url" ]]; then
read -p "Please enter your Jamf Pro server URL : " jamfpro_url
fi
if [[ -z "$jamfpro_user" ]]; then
read -p "Please enter your Jamf Pro user account : " jamfpro_user
fi
if [[ -z "$jamfpro_password" ]]; then
read -p "Please enter the password for the $jamfpro_user account: " -s jamfpro_password
fi
echo
# Remove the trailing slash from the Jamf Pro URL if needed.
jamfpro_url=${jamfpro_url%%/}
GetJamfProAPIToken() {
# This function uses Basic Authentication to get a new bearer token for API authentication.
# Use user account's username and password credentials with Basic Authorization to request a bearer token.
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
api_token=$(/usr/bin/curl -X POST –silent -u "${jamfpro_user}:${jamfpro_password}" "${jamfpro_url}/api/v1/auth/token" | python -c 'import sys, json; print json.load(sys.stdin)["token"]')
else
api_token=$(/usr/bin/curl -X POST –silent -u "${jamfpro_user}:${jamfpro_password}" "${jamfpro_url}/api/v1/auth/token" | plutil -extract token raw -)
fi
}
APITokenValidCheck() {
# Verify that API authentication is using a valid token by running an API command
# which displays the authorization details associated with the current API user.
# The API call will only return the HTTP status code.
api_authentication_check=$(/usr/bin/curl –write-out %{http_code} –silent –output /dev/null "${jamfpro_url}/api/v1/auth" –request GET –header "Authorization: Bearer ${api_token}")
}
CheckAndRenewAPIToken() {
# Verify that API authentication is using a valid token by running an API command
# which displays the authorization details associated with the current API user.
# The API call will only return the HTTP status code.
APITokenValidCheck
# If the api_authentication_check has a value of 200, that means that the current
# bearer token is valid and can be used to authenticate an API call.
if [[ ${api_authentication_check} == 200 ]]; then
# If the current bearer token is valid, it is used to connect to the keep-alive endpoint. This will
# trigger the issuing of a new bearer token and the invalidation of the previous one.
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
api_token=$(/usr/bin/curl "${jamfpro_url}/api/v1/auth/keep-alive" –silent –request POST –header "Authorization: Bearer ${api_token}" | python -c 'import sys, json; print json.load(sys.stdin)["token"]')
else
api_token=$(/usr/bin/curl "${jamfpro_url}/api/v1/auth/keep-alive" –silent –request POST –header "Authorization: Bearer ${api_token}" | plutil -extract token raw -)
fi
else
# If the current bearer token is not valid, this will trigger the issuing of a new bearer token
# using Basic Authentication.
GetJamfProAPIToken
fi
}
InvalidateToken() {
# Verify that API authentication is using a valid token by running an API command
# which displays the authorization details associated with the current API user.
# The API call will only return the HTTP status code.
APITokenValidCheck
# If the api_authentication_check has a value of 200, that means that the current
# bearer token is valid and can be used to authenticate an API call.
if [[ ${api_authentication_check} == 200 ]]; then
# If the current bearer token is valid, an API call is sent to invalidate the token.
authToken=$(/usr/bin/curl "${jamfpro_url}/api/v1/auth/invalidate-token" –silent –header "Authorization: Bearer ${api_token}" -X POST)
# Explicitly set value for the api_token variable to null.
api_token=""
fi
}
GetJamfProAPIToken
APITokenValidCheck
echo "$api_authentication_check"
echo "$api_token"
CheckAndRenewAPIToken
APITokenValidCheck
echo "$api_authentication_check"
echo "$api_token"
InvalidateToken
APITokenValidCheck
echo "$api_authentication_check"
echo "$api_token"

  1. Brian Martin
    May 23, 2024 at 6:14 pm

    One comment I’ll leave…since I got snagged by the whole using basic authentication thing, and since school is out and I have more time, I decided to take a moment and read up on going a step further and using client ID and secret along with the bearer tokens instead of using traditional credentials.

    An hour or two later and some head-banging on ‘why aren’t things working’ and I now have working classic API scripts that make use of the modern security features. My next stop is teaching myself modern Jamf API instead of Classic API but that is another day’s project.

  2. lazymutt
    May 29, 2024 at 8:30 pm

    For folks still using Python, I have a couple demo scripts for the Pro API here: https://github.com/lazymutt/Jamf-Pro-API-Sampler

  1. No trackbacks yet.

Leave a comment