Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The mechanics of token retrieval and token validation (both described later) will differ across OAuth deployments.  For example, for token retrieval, each deployment will inject credentials to the token endpoint differently, and the parameters sent to the token endpoint may also differ.  Token validation will also differ because OAuth supports multiple methods of validation.  Configuration of the retrieval and validation mechanisms, which are done via JAAS configuration, must therefore be flexible.  In particular, while we collaboratively use instances implementing javax.security.auth.Callback and javax.security.auth.CallbackHandler to retrieve information, we can't know in advance what information will be required in order to retrieve or vlidate validate a token; a username and password might – or might not – be required, for example, and retrieval and validation will likely require much more as qwellwell.  We also don't know where this information will come from: a file?  an environment variable?  a database?  Somewhere else?  We need implementations of the Callback and CallbackHandler interfaces that are just as flexible as we need the JAAS configuration to be.

...

Code Block
languagejava
titleorg.apache.kafka.common.security.oauthbearer.SubstitutableModuleOptionsCallbackHandler
collapsetrue
package org.apache.kafka.common.security.oauthbearer;

/**
 * A {@code CallbackHandler} that handles introspection requests against a JAAS
 * configuration
 *
 * @see SubstitutableModuleOptionsCallback
 * @see SubstitutableModuleOptions
 */
public class SubstitutableModuleOptionsCallbackHandler implements CallbackHandler {
    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof SubstitutableModuleOptionsCallback) {
                SubstitutableModuleOptionsCallback substitutableModuleOptionsCallback = (SubstitutableModuleOptionsCallback) callback;
                // only perform substitution if it has not yet been done
                if (substitutableModuleOptionsCallback.substitutionValue() != null)
                    continue;
                String optionName = substitutableModuleOptionsCallback.optionName();
                SubstitutableModuleOptions substitutableModuleOptions = substitutableModuleOptionsCallback
                        .substitutableModuleOptions();
                String rawValue = substitutableModuleOptions.moduleOptionsMap().get(optionName);
                if (rawValue != null) {
                    Object substitutionValue = getSubstitutionValue(optionName, rawValue);
                    if (substitutionValue instanceof String)
                        substitutableModuleOptionsCallback.setSubstitutionValue((String) substitutionValue);
                    else
                        substitutableModuleOptionsCallback.setSubstitutionValue((Password) substitutionValue);
                }
            } else
                throw new UnsupportedCallbackException(callback,
                        String.format("Unrecognized Callback type: %s", callback.getClass().getName()));
        }
    }
 
    /*
     * Handle substitution, dealing with circular references, constraints, etc.
     */
    private Object getSubstitutionValue(String optionName, String rawValue) throws IOException {
        // etc...
    }
 
    // etc...
}

...