Scope policy to Azure AD group PI

KyleEricson
Valued Contributor II

I know there was a PI issue for not being able to scope policies to Azure AD groups at check-in. 

If you signed into Self Service and had the policy set for Self Service it would work, but setting the policy to check-in with scope to All Computers and a limitation of the Azure AD group didn't work.

 

Has anyone heard if this is fixed Jamf didn't give me a PI issue for this?

Read My Blog: https://www.ericsontech.com
11 REPLIES 11

andymcp
New Contributor III

I was given PI-010002 for a version of this issue at one point but I've also been told it has been resolved... which it's not. I'd like to use Azure AD groups for config profile exclusions and eventually be able to use Azure AD groups as a "Limitation". Both of these worked with our on-prem AD but do not function with Azure. It's been very frustrating because I can't get a straight answer as to what LDAP scoping features work with Azure Cloud IdP and which ones don't or what the roadmap is for Azure to have feature parity with traditional LDAP servers.

KyleEricson
Valued Contributor II

@andymcp Thank you for this info I will email Jamf to get a new PI for this.

Read My Blog: https://www.ericsontech.com

KyleEricson
Valued Contributor II

@andymcp 
Hey just got this from support can you see if you still have this issue?

Thank you for sharing that Jamf Nation thread. I was able to pull up that known issue mentioned by the other poster PI104062 - PI-010002 which has the following description: "When Azure is configured as a cloud identity provider, Jamf Pro sometimes fails to correctly handle the directory workflows for Azure groups (e.g., scope limitations)." Request_BadRequest ERROR can be found when scoping to all users and limiting using an AzureAD group and we see a failure when doing a group lookup despite mappings being set correctly and the application being configured in Azure AD. Does this sound like the issue you were looking for? What version of Jamf Pro are you running? It appears this issue was marked closed as of Jamf Pro 10.34. Are you still experiencing the Request_BadRequest ERROR if we look in the server logs when trying to scope this way?

Read My Blog: https://www.ericsontech.com

BTron
New Contributor II

When speaking to support I received this bug #:

PI104479 - Directory based (LDAP, Azure) Limitations/Exclusions do not work for macOS.

My workaround for this is pretty involved, but hey it works...

This is an Extension Attribute to check if Azure AD users belong to Azure AD groups by calling to the API. Then you can create smart groups using the extension attribute. 

#!/bin/zsh

#API Username and Password
username=""
password=""
url="https://company.jamfcloud.com"
loggedInUser=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' )
echo $loggedInUser

#Variable declarations
bearerToken=""
tokenExpirationEpoch="0"
aduser="$loggedInUser@company.com"

#AD group you are checking membership against
adgroup=""

getBearerToken() {
	response=$(curl -s -u "$username":"$password" "$url"/api/v1/auth/token -X POST)
	#checks if OS is below 12
	if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
		bearerToken=$(echo "$response" | /usr/bin/awk -F \" 'NR==2{print $4}' <<< "$bearerToken" | /usr/bin/xargs)
		tokenExpiration=$(echo "$response" | grep "expires" | awk '{ print $3 }' | sed "s/\"//g")
	else
		bearerToken=$(echo "$response" | plutil -extract token raw -o - -)
		tokenExpiration=$(echo "$response" | plutil -extract expires raw - | awk -F . '{print $1}')
	fi
}

checkTokenExpiration() {
	if (("$tokenExpirationEpoch" > "$(date +%s)"))
	then
		echo "Token valid until the following epoch time: " "$tokenExpirationEpoch"
	else
		echo "No valid token available, getting new token"
		getBearerToken
	fi
}

invalidateToken() {
	responseCode=$(curl -w "%{http_code}" -H "Authorization: Bearer ${bearerToken}" $url/api/v1/auth/invalidate-token -X POST -s -o /dev/null)
	if [[ ${responseCode} == 204 ]]
	then
		echo "Token successfully invalidated"
		bearerToken=""
		tokenExpirationEpoch="0"
	elif [[ ${responseCode} == 401 ]]
	then
		echo "Token already invalid"
	else
		echo "An unknown error occurred invalidating the token"
	fi
}

checkTokenExpiration
membership=$(curl -X POST "$url/api/v1/cloud-idp/1/test-user-membership" -H  "accept: application/json" -H  "Authorization: Bearer ${bearerToken}" -H  "Content-Type: application/json" -d "{\"username\":\"$aduser\",\"groupname\":\"$adgroup\"}" | grep "isMember" | awk '{ print $3 }')
echo "<result>$membership</result>"

 

robinds
New Contributor

Hello BTron,

I tried your script as well but it's not working for me. Maybe I am missing something. Can you tell me whether the below points are correct:

username - Admin Username of Jamf server portal

password - Password of the Jamf portal

url - URL of Jamf Cloud server

Anything else do we have to add?

BTron
New Contributor II

Hi @robinds,

There are a number of variables you will need to declare in the script in order for it to function. 

  1. API Username and Password: This is a user that you will create in Jamf Pro with the necessary permissions to accomplish whatever API call you are trying to use. So log into Jamf and go to Settings > Users accounts and groups > create a standard user. Use the username and password for that user in the script. 
  2. URL is correct, this should be the URL of your Jamf Server
  3. aduser: I grabbed the username of whoever is logged into the computer, you will need to modify the company name to whatever your UPN format is. For example $loggedinuser@jamf.com 
  4. adgroup: This is the name AD group you will be checking against. 

I hope this helps!

Mic
New Contributor II

It works fine, thanks @BTron 

I just want to add that you also have to check the IdP # into the Jamf Pro instance, in your script you set it as #1 but it is a variable.

Capside
New Contributor

Hello Mic, where can I find this id in Jamf Pro? 

BTron
New Contributor II

https://developer.jamf.com/jamf-pro/reference/get_v1-cloud-idp 

if you run this API call it will list the cloud IDPs and their IDs

BTron
New Contributor II

Here is an updated script that will fill the Cloud IDP ID automatically. A new variable will need to be declared, in the idpname="Display Name of the IDP in Jamf". Populate this with whatever you named the IDP in Jamf Pro. 

#!/bin/zsh

#API Username and Password
username=""
password=""

#URL of your Jamf Cloud 
url="https://company.jamfcloud.com"

#Find the logged in user
loggedInUser=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' )
echo $loggedInUser

#Variable declarations
bearerToken=""
tokenExpirationEpoch="0"

#Modify the domain name to match your UPN structure
aduser="$loggedInUser@company.com"

#Azure IDP display name located in Jamf Pro Cloud Identity Providers Settings.
idpname="Display Name of the IDP in Jamf"


#AAD group you are checking membership against
adgroup=""

getBearerToken() {
	response=$(curl -s -u "$username":"$password" "$url"/api/v1/auth/token -X POST)
	bearerToken=$(echo "$response" | plutil -extract token raw -)
	tokenExpiration=$(echo "$response" | plutil -extract expires raw - | awk -F . '{print $1}')
	tokenExpirationEpoch=$(date -j -f "%Y-%m-%dT%T" "$tokenExpiration" +"%s")
}


checkTokenExpiration() {
    nowEpochUTC=$(date -j -f "%Y-%m-%dT%T" "$(date -u +"%Y-%m-%dT%T")" +"%s")
    if [[ tokenExpirationEpoch -gt nowEpochUTC ]]
    then
        echo "Token valid until the following epoch time: " "$tokenExpirationEpoch"
    else
        echo "No valid token available, getting new token"
        getBearerToken
    fi
}

invalidateToken() {
	responseCode=$(curl -w "%{http_code}" -H "Authorization: Bearer ${bearerToken}" $url/api/v1/auth/invalidate-token -X POST -s -o /dev/null)
	if [[ ${responseCode} == 204 ]]
	then
		echo "Token successfully invalidated"
		bearerToken=""
		tokenExpirationEpoch="0"
	elif [[ ${responseCode} == 401 ]]
	then
		echo "Token already invalid"
	else
		echo "An unknown error occurred invalidating the token"
	fi
}


#Get Cloud IDP ID
checkTokenExpiration
cloudidpid=$(curl -X GET "$url/api/v1/cloud-idp?page=0&page-size=100&sort=id%3Adesc" \
-H  "accept: application/json" \
-H  "Authorization: Bearer ${bearerToken}")
azureidp=$(echo $cloudidpid | grep -E "id|$idpname" | grep -v "providerName" )
idpid=$(echo $azureidp | grep -m 1 "id" | cut -d '"' -f4 )
echo $idpid

membership=$(curl -X POST \
"$url/api/v1/cloud-idp/$idpid/test-user-membership" \
-H  "accept: application/json" -H  "Authorization: Bearer ${bearerToken}" \
-H  "Content-Type: application/json" \
-d "{\"username\":\"$aduser\",\"groupname\":\"$adgroup\"}" | grep "isMember" | awk '{ print $3 }')
echo "<result>$membership</result>"

invalidateToken

 

Capside
New Contributor

Thank you, this will be useful to many integrators once the PIs are resolved.