/** * Attaches SASL extensions to the Subject */ private void identifyExtensions() throws LoginException { SaslExtensionsCallback extensionsCallback = new SaslExtensionsCallback(); try { callbackHandler.handle(new Callback[] {extensionsCallback}); extensionsRequiringCommit = extensionsCallback.extensions(); } catch (IOException e) { log.error(e.getMessage(), e); throw new LoginException("An internal error occurred while retrieving SASL extensions from callback handler"); } catch (UnsupportedCallbackException e) { extensionsRequiringCommit = EMPTY_EXTENSIONS; log.debug("CallbackHandler {} does not support SASL extensions. No extensions will be added", callbackHandler.getClass().getName()); } if (extensionsRequiringCommit == null) { log.error("SASL Extensions cannot be null. Check whether your callback handler is explicitly setting them as null."); throw new LoginException("Extensions cannot be null."); } }
@Override public void close() { for (LoginManager loginManager : loginManagers.values()) loginManager.release(); loginManagers.clear(); for (AuthenticateCallbackHandler handler : saslCallbackHandlers.values()) handler.close(); }
for (Map.Entry<String, AuthenticateCallbackHandler> entry : saslCallbackHandlers.entrySet()) { String mechanism = entry.getKey(); entry.getValue().configure(configs, mechanism, jaasContexts.get(mechanism).configurationEntries());
private LoginManager(JaasContext jaasContext, String saslMechanism, Map<String, ?> configs, LoginMetadata<?> loginMetadata) throws LoginException { this.loginMetadata = loginMetadata; this.login = Utils.newInstance(loginMetadata.loginClass); loginCallbackHandler = Utils.newInstance(loginMetadata.loginCallbackClass); loginCallbackHandler.configure(configs, saslMechanism, jaasContext.configurationEntries()); login.configure(configs, jaasContext.name(), jaasContext.configuration(), loginCallbackHandler); login.login(); }
private void identifyToken() throws LoginException { OAuthBearerTokenCallback tokenCallback = new OAuthBearerTokenCallback(); try { callbackHandler.handle(new Callback[] {tokenCallback}); } catch (IOException | UnsupportedCallbackException e) { log.error(e.getMessage(), e); throw new LoginException("An internal error occurred while retrieving token from callback handler"); } tokenRequiringCommit = tokenCallback.token(); if (tokenCallback.errorCode() != null) { log.info("Login failed: {} : {} (URI={})", tokenCallback.errorCode(), tokenCallback.errorDescription(), tokenCallback.errorUri()); throw new LoginException(tokenCallback.errorDescription()); } }
/** * Decrease the reference count for this instance and release resources if it reaches 0. */ public void release() { synchronized (LoginManager.class) { if (refCount == 0) throw new IllegalStateException("release() called on disposed " + this); else if (refCount == 1) { if (loginMetadata.configInfo instanceof Password) { DYNAMIC_INSTANCES.remove(loginMetadata); } else { STATIC_INSTANCES.remove(loginMetadata); } login.close(); loginCallbackHandler.close(); } --refCount; LOGGER.trace("{} released", this); } }
private Map<String, String> processExtensions(OAuthBearerToken token, SaslExtensions extensions) throws SaslException { OAuthBearerExtensionsValidatorCallback extensionsCallback = new OAuthBearerExtensionsValidatorCallback(token, extensions); try { callbackHandler.handle(new Callback[] {extensionsCallback}); } catch (UnsupportedCallbackException e) { // backwards compatibility - no extensions will be added } catch (IOException e) { handleCallbackError(e); } if (!extensionsCallback.invalidExtensions().isEmpty()) { String errorMessage = String.format("Authentication failed: %d extensions are invalid! They are: %s", extensionsCallback.invalidExtensions().size(), Utils.mkString(extensionsCallback.invalidExtensions(), "", "", ": ", "; ")); log.debug(errorMessage); throw new SaslAuthenticationException(errorMessage); } return extensionsCallback.validatedExtensions(); }
private byte[] process(String tokenValue, String authorizationId, SaslExtensions extensions) throws SaslException { OAuthBearerValidatorCallback callback = new OAuthBearerValidatorCallback(tokenValue); try { callbackHandler.handle(new Callback[] {callback}); } catch (IOException | UnsupportedCallbackException e) { handleCallbackError(e); } OAuthBearerToken token = callback.token(); if (token == null) { errorMessage = jsonErrorResponse(callback.errorStatus(), callback.errorScope(), callback.errorOpenIDConfiguration()); log.debug(errorMessage); return errorMessage.getBytes(StandardCharsets.UTF_8); } /* * We support the client specifying an authorization ID as per the SASL * specification, but it must match the principal name if it is specified. */ if (!authorizationId.isEmpty() && !authorizationId.equals(token.principalName())) throw new SaslAuthenticationException(String.format( "Authentication failed: Client requested an authorization id (%s) that is different from the token's principal name (%s)", authorizationId, token.principalName())); Map<String, String> validExtensions = processExtensions(token, extensions); tokenForNegotiatedProperty = token; this.extensions = new SaslExtensions(validExtensions); complete = true; log.debug("Successfully authenticate User={}", token.principalName()); return new byte[0]; }
private byte[] clientInitialResponse(String authorizationId, boolean illegalToken, Map<String, String> customExtensions) throws OAuthBearerConfigException, IOException, UnsupportedCallbackException { OAuthBearerTokenCallback callback = new OAuthBearerTokenCallback(); LOGIN_CALLBACK_HANDLER.handle(new Callback[] {callback}); OAuthBearerToken token = callback.token(); String compactSerialization = token.value(); String tokenValue = compactSerialization + (illegalToken ? "AB" : ""); return new OAuthBearerClientInitialResponse(tokenValue, authorizationId, new SaslExtensions(customExtensions)).toBytes(); } }