Skip to main content

Updated 14SEPT2022 - I moved the GitHub link over to the official Jamf Github - https://github.com/jamf/jamfconnect/tree/main/azure_conditional_access will have the latest until the official Jamf Connect docs get updated.

Updated 14JUL2022 - The github link below has been updated with some steps removed for version 2.13 or greater of Jamf Connect, details about custom ROPG scopes in the menu bar, notes on how the login may still show a failure after doing this but that's fine.  https://www.jamf.com/blog/how-to-azure-conditional-access-and-jamf-connect/ will supersede instructions currently on the Jamf Blog.

Updated 14JAN2022 - The github link below has been updated to simplify the setup of the application registrations in Azure and allows for full testing in Jamf Connect Configuration before deploying to a test machine.

https://www.jamf.com/blog/how-to-azure-conditional-access-and-jamf-connect/  - Updated instructions posted to Jamf Blog.

UPDATED: 10 December 2021 - Includes information on how to create a custom scope for Microsoft Azure Conditional Access policies.

Overview: This covers the following topics:
  • Administrators finding "failed" login attempts in Azure sign-in logs when using Jamf Connect
  • How the ROPG workflow and Jamf Connect communicate
  • How to make an App Registration in Microsoft Azure Active Directory that allows for Conditional Access policies
  • How to make Conditional Access policies NOT apply to the ROPG workflow

Problem:

Administrators may observe failed login attempts in the log for the enterprise application created in Microsoft Azure Active Directory when using Jamf Connect and a Conditional Access policy that requires multi-factor authentication for the target of "All cloud apps." While this is expected behavior of the Resource Owner Password Grant (ROPG) workflow, it may trigger a user appearing in the Risky Sign-Ins in Azure Active Directory security reports.

What is happening:

The target of "All cloud apps" applies policies far beyond the logins to specific cloud services and applies policies to non-interactive workflows like those with ROPG.  Specifically, the "All cloud apps" appears to apply to any application requesting a login with the scope of any of the following:

 

 

 

 

 

 

openid profile email

 

 

 

 

 

 

The Open ID Connect 2.0 specification uses these default scopes to obtain an access or identity token for a client application.  Consequently, in its default configuration, Jamf Connect login uses the "openid profile email" scope in its authentication requests, and the only way to apply a CA policy in this default behavior is to apply the policy to "All cloud apps" with NO exceptions applied or the CA policy will break.

 
Administrators have multiple options for solutions to enforce MFA on the Jamf Connect login screen:
  • Simplest, but most impact on user logins: Set hard requirements for MFA via the older method of Azure Multi-Factor Authentication which applies an MFA requirement to ALL logins to ANY service for a specific user.  Ignore failed logins in the sign-in logs for ROPG checks of the password.  (Additional information on how to determine if a failed login is due to Jamf Connect menu bar agent doing an ROPG request is below.)
  • Simple, but may affect other services: Apply a Conditional Access policy applied to "All cloud apps" requiring Multi-factor Authentication for login.  Do NOT use an exception to the policy as that appears to break functionality of the CA rule as of testing done 10DEC2021.  Ignore failed logins in the sign-in logs for ROPG checks of the password.
  • Complex, but exacting: Follow the instructions from https://github.com/jamf/jamfconnect/tree/main/azure_conditional_access to create a custom scope for Jamf Connect applications.  Verify that no policies are created that apply to "All cloud apps" as to not affect the ROPG workflow.  CA policy will be applied as expected to the Jamf Connect login application and ROPG check will appear as a successful login in sign-in logs.

Azure Multi-factor Authentication vs. Conditional Access

Administrators can enable multi-factor authentication requirements for a user account in two ways:
  • Multi-factor Authentication which is reachable via the “All services” list in the Azure portal
  • Conditional Access which is reachable via Azure Active Directory under Security
Multi-factor Authentication is a system wide, all login attempts, master switch system for enforcing MFA at authentication. While IP address ranges can be exempted, the rules apply to all authentications.
Conditional Access allows for fine grain details to apply for when MFA is required including exempting MFA for web applications. 

Resource Owner Password Grant workflow

Jamf Connect uses a Resource Owner Password Grant (ROPG) workflow to synchronize the user’s password in the identity provider with the password on the user’s client machine. The user name and the password are sent to the identity provider in a “non-interactive” login to receive a response. This means that the user is not prompted for any sort of user name or password when logging in; Jamf Connect is using the information securely stored in the user’s keychain for this event.
 
For Azure, the responses are one of the following:
  • Success, no MFA requirements: An access, refresh, and ID token encoded in HS256
  • Success, MFA required through a policy: An error response like 

 

 

 

 

 

 

AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access iapplication UUID]

 

 

 

 

 

 

  • Failure, bad password or user name: An error response like 

 

 

 

 

 

 

AADSTS50126: Error validating credentials due to invalid username or password.

 

 

 

 

 

 

As long as the user password is correct, the ROPG flow has succeeded - the password has been validated to be correct. Whereas Jamf Connect has no need for the access, refresh, and ID token to keep the local password in sync with the identity provider, an appropriate error response is interpreted as a successful password check.
 

Diagnosing MFA vs. failed password in Azure logs

Navigate to Azure Active Directory → Enterprise Applications and select the name of your Jamf Connect application in Azure. Navigate to Activity → Sign-ins to open user usage logs.

Shown above are two logins which appear to be failures. Under the “Authentication required” column, the first login says “Multi-factor authentication”. Clicking on the row will pull up additional details about the login attempt.

Under Authentication Details, the “Result detail” will let an administrator determine if the login was successful or a failure. In this example, the login was a success - the Result detail shows that the “User did not pass the MFA challenge (non interactive).” This login can be interpreted in that the user was required to use MFA by either a Conditional Access policy or through Azure Multi-factor authentication.

In the second example, a user with MFA required failed to enter their correct password:

The Authentication required column shows “Single-factor authentication” and the Authentication Details show “Invalid username or password or Invalid on-premise username or password.” While the user is required to use Multi-factor authentication, the user failed the first, single factor and thus was never prompted for MFA.

Creating a custom scope for Jamf Connect

To eliminate the inaccurate "failed responses" for ROPG, admins must remove any "All cloud apps" scoped requirements for multi-factor authentication and create a custom scope for Jamf Connect login.

Follow the guide in Azure_Conditional_Access_and_Jamf_Connect.pdf (source: GitHub) for step by step instructions.

Conditional Access Policy Considerations

Several Conditional Access Grant policies can create unacceptable behavior to access a client device:

  • Require device to be marked as compliant
  • Require Hybrid Azure AD joined device

In the above cases, a user would be unable to log into a client machine to fix the issue of being out of compliance by running a Jamf Pro policy to get the device back into compliance.

  • Require approved client app
  • Require app protection policy

In the above cases, the Jamf Connect software is not of the Microsoft apps accessing a specific service (for example, Microsoft Outlook accessing O365 mail), and all access would be blocked.

Administrators are recommended to carefully read conditional access polices and conditions applied to avoid locking users out of client devices inadvertently.

In regards to the following:

(H3) Step Four: Remove any Conditional Access policies applied to All cloud apps Navigate to
portal.azure.com → Azure Conditional Access. Examine any application applied to the scope of “All
cloud apps”. Either set “Enable policy” to “Off” for any application that has a Grant of “Require
multi-factor authentication” or modify the “Cloud apps or actions” to specifically list resources
that should have MFA applied.Applying a policy to require MFA for “All cloud apps” will cause the ROPG application in the next
step to inaccurately show failed logins in the Azure sign-in
logs.

Rather than modify "All cloud apps" to include all apps except Jamf, can Jamf just be added as an exclusion to existing CA's that require MFA? Would it just be "Jamf Connect - Conditional Access Policy API" that needs to be excluded?


Yes, you can definitely do that.  And correct, the "private" app registration will be the app you want to add to the "Exclude" list in the Conditional Access policy.


Anyone seeing an "AADSTS500113: No reply address is registered for the application"?  I walked thru all of the steps and still get this.  We are using Duo for MFA and it works, but gives this error after.  


Anyone seeing an "AADSTS500113: No reply address is registered for the application"?  I walked thru all of the steps and still get this.  We are using Duo for MFA and it works, but gives this error after.  


Never mind, figured it out.  Had to add https://127.0.0.1/jamfconnect to the Conditional Access app registration.  Now it works fine.


So to be clear - this will result in the following? 

Jamf Connect logging failures in Azure with the 50076 sign in error code, even when the MFA has prompted and been accepted by the Mac? Is there a way to have the 50076 errors in Azure show as successes instead of failures?

We're worried about the constant failures resulting in the triggering of a block out for the user. 
We're on 2.14 and have configured things to spec per the instructions and the chat here. Just want to make sure I can properly communicate what's occurring back to the powers that be. Or if we need to tweak something - that we do so.  Thanks in advance for any input. 


So to be clear - this will result in the following? 

Jamf Connect logging failures in Azure with the 50076 sign in error code, even when the MFA has prompted and been accepted by the Mac? Is there a way to have the 50076 errors in Azure show as successes instead of failures?

We're worried about the constant failures resulting in the triggering of a block out for the user. 
We're on 2.14 and have configured things to spec per the instructions and the chat here. Just want to make sure I can properly communicate what's occurring back to the powers that be. Or if we need to tweak something - that we do so.  Thanks in advance for any input. 


The error isn't really an error - it's just an interrupted login.  By the time the user needs to MFA in the password check to get an access token, Jamf Connect already knows the password is right.

If we think of the menu bar agent as the thing that checks the local client password against the cloud password, we don't really need the full access/ID/refresh tokens that would be sent down to the client if the user actually did the MFA.  JC would look at that and say, "Thanks, but..." and then pitch those into the bit bucket anyway.  JC got what it needed - was the password right?  If you're prompting for MFA, then the password HAD to be right.

What the "complex but exacting" method of setting up two apps does will exclude the "public" endpoint, the one that does ROPG, from needing MFA at all.  This will eliminate the 50076 errors.  When the user is doing an interactive login (aka logging into the Mac, seeing the Azure login web page) then they'll be prompted for MFA because the scope requests access to a resource that needs MFA.

It's confusing, but it eliminates the errors in the logs.


Sample configuration profile with this setup:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AllowNetworkSelection</key>
<true/>
<key>CreateJamfConnectPassword</key>
<true/>
<key>OIDCAdmin</key>
<array>
<string>Admin</string>
</array>
<key>OIDCAdminAttribute</key>
<string>roles</string>
<key>OIDCClientID</key>
<string>[YOUR PUBLIC APPLICATION UUID STRING HERE]</string>
<key>OIDCDiscoveryURL</key>
<string>https://login.microsoftonline.com/[YOUR TENANT UUID STRING HERE]/v2.0/.well-known/openid-configuration</string>
<key>OIDCNewPassword</key>
<false/>
<key>OIDCProvider</key>
<string>Azure</string>
<key>OIDCROPGID</key>
<string>[YOUR PUBLIC APPLICATION UUID STRING HERE]</string>
<key>OIDCRedirectURI</key>
<string>https://127.0.0.1/jamfconnect</string>
<key>OIDCScopes</key>
<string>api://[YOUR RANDOMLY GENERATED API IDENTIFIER HERE]/jamfconnect+openid+profile+email</string>
<key>OIDCTenant</key>
<string>[YOUR TENANT UUID STRING HERE]</string>
<key>OIDCUsePassthroughAuth</key>
<true/>
<key>ROPGDiscoveryURL</key>
<string>https://login.microsoftonline.com/[YOUR TENANT UUID STRING HERE]/.well-known/openid-configuration</string>
<key>ROPGTenant</key>
<string>[YOUR TENANT UUID STRING HERE]</string>
</dict>
</plist>

I do not see the ROPG Scopes key in this example and when trying to add it in JC Configurator, I get a invalid keys error and it removes them.  


@rabbitt Is this configuration still the recommended process? Or should we migrate to use the custom security attributes - from my brief reading it seems the security attribute should be applied to the ROPG application, right?  I also see the option to provide an application direct access to the Password Hash Sync in Azure.  Does this remove the requirement for creating separate applications in Azure for OIDC and ROPG?  If not, which application should I apply the Azure Password Hash Sync policy to?


@rabbitt Is this configuration still the recommended process? Or should we migrate to use the custom security attributes - from my brief reading it seems the security attribute should be applied to the ROPG application, right?  I also see the option to provide an application direct access to the Password Hash Sync in Azure.  Does this remove the requirement for creating separate applications in Azure for OIDC and ROPG?  If not, which application should I apply the Azure Password Hash Sync policy to?


https://github.com/jamf/jamfconnect/tree/main/azure_conditional_access has the current guidance (just substitute "Entra ID" for anytime I say "Azure."



  • Create the custom security attribute.

  • Apply the custom security attribute as an "exception" to any policy that is applied to "All cloud apps."

  • Apply the custom security attribute to the "public" app registration you made for Jamf Connect.

  • Do NOT apply the custom security attribute to the "API" (or "private") app registration you make for Jamf Connect

  • Add the "API" app to your conditional access policy that requires MFA

  • Change your Jamf Connect Login configuration to have a custom OIDCScope that calls the "API" app


When ROPG happens, no MFA required, asks the "public" app to confirm the password, gets a token back in response if the password is right.


When OIDC happens, "public" app asks the "API" app for something (that's the custom OIDCScope asking the API to get involved.)  API app is subject to MFA.  User prompted for MFA as part of the login.  Response is a token if the user successfully completes authentication.


Password Hash Sync access _should_ be enabled for apps by default, but if it's not, that's where the powershell script to create a special policy for Jamf Connect kicks in.  Separate from the conditional access stuff.


So just to clarify, is the only negative consequence of not creating the exception simply just log noise?

One thing I think that JAMF has failed to disclose in the doco (https://learn.jamf.com/en-US/bundle/jamf-connect-documentation-current/page/Modifying_Jamf_Connect_for_Conditional_Access_Polices.html) is the negative consequences of adding an exception to a Conditional Access policy which is scoped to ‘All resources (formerly 'All cloud apps')’. It then excludes certain ‘low privilege scopes’ for MS graph:

see: https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-cloud-apps#conditional-access-behavior-when-an-all-resources-policy-has-an-app-exclusion

In practice we immediately noticed side effects like using low level PowerShell commands like connecting to graph with ‘connect-mggraph’ no longer requiring MFA. The work around for these scopes in the above article isn’t consistent either in testing and probably would just reintroduce the ROPG logging issue above.

Has anyone got any clarification for the question at the start of the post please?

__PRESENT


Reply