public boolean authenticate(String digest) {
        // Perform authentication. Wait for the handshake (with the secret key)
        String secretKey = ExternalComponentManager.getSecretForComponent(defaultSubdomain);
        String anticipatedDigest = AuthFactory.createDigest(getStreamID().getID(), secretKey);
        // Check that the provided handshake (secret key + sessionID) is correct
        if (!anticipatedDigest.equalsIgnoreCase(digest)) {
            Log.debug("LocalComponentSession: [ExComp] Incorrect handshake for component with domain: {}", defaultSubdomain);
            // The credentials supplied by the initiator are not valid (answer an error and close the connection).
            conn.close(new StreamError(StreamError.Condition.not_authorized));
            return false;
        }
        else {
            // Component has authenticated fine
            setStatus(Session.Status.AUTHENTICATED);
            // Send empty handshake element to acknowledge success
            conn.deliverRawText("<handshake></handshake>");
            // Bind the domain to this component
            ExternalComponent component = getExternalComponent();
            try {
                InternalComponentManager.getInstance().addComponent(defaultSubdomain, component);
                conn.registerCloseListener(new ConnectionCloseListener() {
                    @Override
                    public CompletableFuture<Void> onConnectionClosing(@Nullable Object handback) {
                        return CompletableFuture.runAsync(() -> InternalComponentManager.getInstance().removeComponent(defaultSubdomain, (ExternalComponent) handback));
                    }
                }, component);
                Log.debug("LocalComponentSession: [ExComp] External component was registered SUCCESSFULLY with domain: {}", defaultSubdomain);
                return true;
            }
            catch (ComponentException e) {
                Log.debug("LocalComponentSession: [ExComp] Another component is already using domain: {}", defaultSubdomain, e);
                // The credentials supplied by the initiator are not valid (answer an error and close the connection).
                conn.close(new StreamError(StreamError.Condition.conflict, "Another component seems to be using this domain."));
                return false;
            }
        }
    }
Authenticate the external component using a digest method. The digest includes the
stream ID and the secret key of the main domain of the external component. A component
needs to authenticate just once but it may bind several domains.

@param digest the digest sent in the handshake.
@return true if the authentication was successful.
xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalComponentSession.java