See: Description
| Interface | Description |
|---|---|
| ChannelShapersFactory |
The
ChannelShapersFactory created of actual ChannelShapers based on
the session, which is provided by the corresponding QDAuthRealm. |
| QDAuthRealm |
This is server-side authentication provider that resolves
AuthSession. |
| QDAuthRealmFactory |
Factory for
QDAuthRealm. |
| QDLoginHandler |
Framework for the authorization, which must receive and update accessToken for the client.
|
| QDLoginHandlerFactory |
Factory for
QDLoginHandler. |
| Class | Description |
|---|---|
| BasicAuthRealmFactory |
Basic implementation for
QDAuthRealmFactory. |
| BasicChannelShaperFactory | |
| BasicLoginHandler |
Basic implementation for
QDAuthRealm. |
| BasicLoginHandlerFactory |
Basic implementation for
QDLoginHandlerFactory. |
| ConsoleLoginHandlerFactory |
ProtocolDescriptor properties carry auth state:
authentication — sent by server: challenge, error, or success signalauthorization — sent by client: credentials token| Property | Value | Meaning |
|---|---|---|
authentication | "LOGIN <realm>" |
Server challenges client (like HTTP WWW-Authenticate) |
authentication | non-empty error string | Server reports auth failure |
authentication | "" (empty) |
Server confirms success (like HTTP 200 OK) |
authentication | absent | No change; receiver retains last value |
authorization | token string | Client sends credentials (like HTTP Authorization) |
Properties accumulate across DESCRIBE_PROTOCOL messages within a connection.
A property not present in a new message survives from the previous descriptor.
The only way to clear a property on the remote side is to send an explicit replacement value.
Server Client | | |--- authentication="LOGIN MyRealm" --------->| (challenge) | | | [QDLoginHandler.login() -> Promise] | | | |<-- authorization="Basic dXNlcjpwYXNz" ------| (credentials) | | | [QDAuthRealm.authenticate() -> Promise] | | | |--- authentication="" ---------------------->| (success + data flow begins) | |
authenticate() promise rejects: AuthManager moves to AUTH_FAILED,
the failure message is sent as a non-empty authentication value. The client treats
any non-empty authentication value as a fresh login prompt and re-runs
login(reason) with the error text.
Server Client
|<-- authorization="Basic dXNlcjpwYXNz" ------|
| [QDAuthRealm.authenticate() rejects] |
|--- authentication="bad credentials" ------->| (failure, NOT empty)
| |
| [QDLoginHandler.login("bad ...")] |
|<-- authorization="Basic dXNlcjpwYXNzMg==" --| (retry with new token)
| |
DESCRIBE_PROTOCOL messages, so a peer that
re-emits a property the other side has already processed must not re-invoke the
QDAuthRealm / QDLoginHandler
implementation.
On the server side MessageAdapter guards by lastProcessedAuthToken: an
authorization with the same token as the previous call is dropped before reaching
authManager.authenticate(). On the client side LoginManager guards by
lastSendAccessToken and ignores a repeated "LOGIN ..." challenge while
already in LOGIN / WAITING_OTHER_SIDE / COMPLETED.
DESCRIBE_PROTOCOL carrying
an unrelated delta (e.g. client-side setRequestedAggregationPeriod). The auth
properties are NOT re-attached: LoginManager skips writing authorization
while in WAITING_OTHER_SIDE / COMPLETED, and MessageAdapter writes
authentication="" on every outgoing descriptor only because the receiver already
processed it once and discards the redundant repeat.
Server Client |--- authentication="" ---------------------->| (auth complete) |<-- requestedAggregationPeriod="1s" ---------| (delta only, NO authorization re-sent) | |
Implement QDAuthRealm and register via
QDAuthRealmFactory (SPI).
The realm's authenticate method
receives the client's token and returns a Promise that resolves
to an AuthSession on success or an exception on failure.
Internally, AuthManager (package-private, in com.devexperts.qd.qtp)
drives the server-side state machine. The on-wire authentication value is split
across two write sites: AuthManager.prepareAuthenticate writes the challenge
("LOGIN <realm>") and the failure string from its reason field, while
MessageAdapter.prepareProtocolDescriptor writes the empty success value directly
based on AuthManager.isAuthComplete(). Both writes are a pure function of
AuthManager's current state and are never consumed by the act of sending — the value
changes only via state transitions.
Implement QDLoginHandler and register via
QDLoginHandlerFactory (SPI).
The handler's login method
receives the server's challenge or error and returns a Promise
that resolves to an AuthToken.
Internally, LoginManager (package-private, in com.devexperts.qd.qtp)
drives the client-side state machine. The authorization value is written by
LoginManager.prepareProtocolDescriptor and, symmetric to the server side, is a
pure function of LoginManager's current state — once the token has been emitted, the
manager moves to WAITING_OTHER_SIDE / COMPLETED and stops re-attaching
the token to subsequent descriptors.
QDAuthRealm,
QDLoginHandler,
ProtocolDescriptorCopyright © 2002–2026 Devexperts LLC. All rights reserved.