As described in Kerberos for Chrome on Android, in Chrome M46 third parties can enable SPNEGO authentication in Chrome for Android. To do this they must provide a SPNEGO Authenticator. This page describes the interface between Chrome and the SPNEGO Authenticator.
The SPNEGO Authenticator is provided by an Android Service. This must be incorporated in an app, provided by the third party, installed on the user’s device. The app is responsible for managing any accounts used for SPNEGO authentication, and for all communication with the SPNEGO server.
The SPNEGO Authenticator is an Android AccountAuthenticator. As such it must follow the pattern described in AbstractAccountAuthenticator. In particular it must implement an authenticator class derived from AbstractAccountAuthenticator.
The SPNEGO Authenticator must define a new account type. Its name should be derived from the writer’s domain name (e.g. com.example.spnego). As explained in Kerberos for Chrome on Android, the account type must be defined to use customTokens. The account type must support the “SPNEGO” feature (HttpNegotiateConstants.SPNEGO_FEATURE).
Chrome finds the SPNEGO authenticator through the Android account type it provides. This is defined by the authenticator, and passed to Chrome through the AuthAndroidNegotiateAccountType policy.
The interface to Chrome is through the Android account management framework, and in particular through AbstractAccountManager.getAuthToken. Chrome, in org.chromium.net.HttpNegotiateConstants, defines some additional keys and values that are used in the arguments to getAuthToken, and in the returned result bundle.
When getAuthToken is called the authTokenType will be "SPNEGO:HOSTBASED:<spn>" where <spn> is the principal for the request. This will always be a host based principal (in the current implementation; future versions may allow other types of principal, but if they do so they will use a different prefix. SPNEGO Authenticators should check the prefix).
The options bundle will contain the keys:
If this is the second or later round of multi-round authentication sequence it will also contain.
The final result bundle of getAuthToken (returned either as the return value of getAuthToken, or through the AccountAuthenticatorResponse) should contain the account name, account type, and token as defined in the Android documentation. The token should be Base64 encoded. In addition the bundle should contain the keys:
The authenticator can get the uid of the calling app using the KEY_CALLER_UID field of the options bundle, and then identify the requesting application using context.getPackageManager().getNameForUid() or similar.
This is required to ensure that malicious apps run by the user cannot use the user’s credentials to access services in unintended ways. This is particularly important since using the custom tokens option (as described above) disables Android’s own signature check when getting auth tokens.
Error codes displayed in Chrome
In addition to the error codes that can be forwarded from the authenticator app, the following errors can be displayed by Chrome when trying to authenticate a request:
Chrome defines a number of policies for controlling the use of SPNEGO authentication. In particular to enable SPNEGO authentication the AuthServerWhitelist must not be empty, and the AuthAndroidNegotiateAccountType must match the account type provided by the SPNEGO authenticator.
To simplify testing of SPNEGO authentication Chrome on Android supports command line options corresponding to these policies. These are “--auth-server-whitelist=<whitelist>” and “--auth-spnego-account-type=<account type>”. To set these, add them to the command line on the device (requires a rooted device).