Setting up ROPG for Password Verification in XCreds
By default, XCreds verifies that a user’s password has not changed by presenting the refresh token obtained at initial login back to the identity provider (IdP). If the refresh token is accepted, then the user’s password is assumed to not have changed. However, this may not be true in all cases. Some IdP’s do not invalidate refresh tokens when a user’s password changes. This results in XCreds verifying the refresh token, but not detecting that the password has changed.
XCreds supports verifying a user’s password is valid by using Resource Owner Password Grant, or ROPG. ROPG is a simple way to verify a password and get OIDC tokens in response. However ROPG does not support multifactor authentication (MFA). If a user’s password is verified with ROPG and MFA is required, the server will respond with an error. The error is unique for MFA when is required, and happens after the password is verified. ROPG can be used to verify the password has not changed by looking for a specific error code after authentication. In some circumstances, this is sufficient to detect password changes. This article outlines how to set up ROPG for password verification in XCreds.
Enabling ROPG for Password Verification
To enable ROPG for password verification, the following XCreds configuration keys must be updated.
shouldUseROPGForPasswordChangeChecking
To enable XCreds to use ROPG for password verification, the preference key shouldUseROPGForPasswordChangeChecking
must be set to true. This results in the XCreds menu item using ROPG when verifying the password without user interaction. If the ROPG request fails, the user is prompted to follow the standard flow for authentication (which may include a web view and MFA).
ropgResponseValue
Note: Available in XCreds 5.1 and later
If multifactor authentication is required for ROPG, set the ropgResponseValue
key to the value that is returned by the ROPG request. For Azure, this is interaction_required
. Other implementations may require a different value.
clientSecret
Client secret is typically optional and only required if set up in the OIDC app. For Azure to use ROPG, the OIDC instance must have a client secret generated in Azure. That value must be added to XCreds preferences in the value for the clientSecret
key.
discoveryURL
The discovery URL must be set to the tenant-specific URL rather than the common value. For example, in Azure, the tenant URL would be something like:
https://login.microsoftonline.com/TENANT_ID/.well-known/openid-configuration
resource
Note: Available in XCreds 5.1 and later
This key adds &resource=value
to the ROPG request (where value is the value set for the resource
key in XCreds preferences). The value for the resource preference is typically set to https://graph.microsoft.com
for Azure and is typically not required for other implementations.
Sample Configuration Profile
Below is a working sample configuration. The clientSecret and tenant have been removed.
<?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>PayloadContent</key>
<array>
<dict>
<key>PayloadDescription</key>
<string>Configures XCreds configuration preferences</string>
<key>PayloadDisplayName</key>
<string>XCreds</string>
<key>PayloadIdentifier</key>
<string>com.github.erikberglund.ProfileCreator.47F59CD0-E476-4016-A8C6-82837B61C7CE.com.twocanoes.xcreds.F5B79C66-146F-4F8A-9237-CAF10606615C.11BE4B70-7A81-4351-A799-6B6BCBCF0900</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.twocanoes.xcreds</string>
<key>PayloadUUID</key>
<string>11BE4B70-7A81-4351-A799-6B6BCBCF0900</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>clientID</key>
<string>5487c4cd-949a-402d-9eee-ae8fb696b415</string>
<key>discoveryURL</key>
<string>https://login.microsoftonline.com/[REDACTED]/.well-known/openid-configuration</string>
<key>redirectURI</key>
<string>https://127.0.0.1/xcreds</string>
<key>shouldUseROPGForPasswordChangeChecking</key>
<true/>
<key>clientSecret</key>
<string>[REDACTED]</string>
<key>resource</key>
<string>https://graph.microsoft.com</string>
</dict>
</array>
<key>PayloadDescription</key>
<string>azure xcreds</string>
<key>PayloadDisplayName</key>
<string>azure xcreds</string>
<key>PayloadIdentifier</key>
<string>com.github.erikberglund.ProfileCreatorAF7B74FE-BF9D-4789-9E78-519C49324120</string>
<key>PayloadOrganization</key>
<string>twocanoes</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>7620DBF9-295B-4DFF-B0AE-0629207ECF5A</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>