...
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 | ||||||
---|---|---|---|---|---|---|
| ||||||
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... } |
...